[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-azure-amg-check-key-vault":3,"mdc-lmtwcx-key":34,"related-repo-azure-amg-check-key-vault":2557,"related-org-azure-amg-check-key-vault":2627},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":24,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"amg-check-key-vault","monitor Azure Key Vault health","Fleet-wide Azure Key Vault health check — pulse check for availability, API latency, throttling (429s), auth failures (401\u002F403), and vault saturation across all vaults, then deep-dives into the top 7 most interesting vaults with metrics and resource logs. Tracks known issues across sessions via persistent report. On first run, auto-discovers datasource UID and prompts for subscription ID.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"azure","Azure (Microsoft)","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fazure.png","Azure",[13,17,20,21],{"name":14,"slug":15,"type":16},"Security","security","tag",{"name":18,"slug":19,"type":16},"Observability","observability",{"name":11,"slug":8,"type":16},{"name":22,"slug":23,"type":16},"Monitoring","monitoring",2,"https:\u002F\u002Fgithub.com\u002FAzure\u002Famg-skills","2026-07-12T08:19:53.484442",null,[],{"repoUrl":25,"stars":24,"forks":24,"topics":30,"description":31},[],"Agent skills for Azure Managed Grafana","https:\u002F\u002Fgithub.com\u002FAzure\u002Famg-skills\u002Ftree\u002FHEAD\u002Fplugins\u002Famg-toolkit\u002Fskills\u002Famg-check-key-vault","---\nname: amg-check-key-vault\ndescription: Fleet-wide Azure Key Vault health check — pulse check for availability, API latency, throttling (429s), auth failures (401\u002F403), and vault saturation across all vaults, then deep-dives into the top 7 most interesting vaults with metrics and resource logs. Tracks known issues across sessions via persistent report. On first run, auto-discovers datasource UID and prompts for subscription ID.\nargument-hint: \"[time-range, e.g. 7d, 1d, 3d] [subscription-id]\"\ndisable-model-invocation: true\neffort: max\nallowed-tools: mcp__amg__amgmcp_pulse_check mcp__amg__amgmcp_query_resource_graph mcp__amg__amgmcp_query_resource_metric mcp__amg__amgmcp_query_resource_metric_definition mcp__amg__amgmcp_query_resource_log mcp__amg__amgmcp_datasource_list mcp__amg__amgmcp_query_activity_log Bash(node *) Glob Read Write Edit\n---\n\n## Runtime Context\n- Current UTC time: !`date -u +%Y-%m-%dT%H:%M:%SZ`\n- Config: !`cat memory\u002Famg-check-key-vault\u002Fconfig.md 2>\u002Fdev\u002Fnull || echo \"NOT_CONFIGURED\"`\n- Prior report: !`[ -f memory\u002Famg-check-key-vault\u002Freport.md ] && echo \"exists ($(grep -c '^### KV-' memory\u002Famg-check-key-vault\u002Freport.md) bugs documented)\" || echo \"not found\"`\n- Arguments: time-range=$0, subscription-override=$1\n\n> **Known Issues**: Before presenting findings, cross-reference results against `memory\u002Famg-check-key-vault\u002Freport.md`.\n\n# Azure Key Vault Health Check\n\nAnalyze Azure Key Vault health using a **two-phase approach**: a single `amgmcp_pulse_check` call for fleet-wide summary, followed by targeted deep dives into the **top 7 most interesting vaults** only.\n\n## Critical Constraints\n\n- **Do NOT use subagents (Agent tool) for MCP queries.** Subagents do not have access to MCP tools. All MCP tool calls must be made directly from the main conversation context.\n- **Deep dive limit: at most 7 vaults.** Select the most interesting vaults from pulse check results. Do not deep-dive the entire fleet.\n- **Time format**: ISO 8601 UTC with explicit `from`\u002F`to` — NEVER use `timespan` (it causes errors).\n- **Parallelism cap**: 30 concurrent MCP calls per batch. Reduce to 4-5 if rate-limited.\n\n## Prerequisites\n\n- An AMG-MCP server must be connected (the `allowed-tools` frontmatter references the MCP server name — update it if your server has a different name)\n- The MCP server's Grafana service account token environment variable must be set\n\n## Configuration\n\n**If Config shows `NOT_CONFIGURED`**: Run [First-Run Setup](#first-run-setup) at the bottom of this file, then return here.\n\n**If Config is populated**: Extract the datasource UID and subscription ID(s) from the pre-loaded Runtime Context above and use them for all queries. Use `$1` as the subscription override if provided.\n\n- **Datasource UID**: from `## Azure Monitor Datasource` > `UID`\n- **Subscription ID(s)**: from `## Subscriptions` (or `$1` if provided)\n- **Resource Type**: `microsoft.keyvault\u002Fvaults` (lowercase)\n- **ARM ID template**: `\u002Fsubscriptions\u002F{SUB}\u002FresourceGroups\u002F{RG}\u002Fproviders\u002FMicrosoft.KeyVault\u002Fvaults\u002F{name}`\n\n## Time Range\n\nDefault is 7 days (`pastDays: 7`) for pulse check and deep-dive metrics, 24 hours for resource logs. If the user specifies a different range via `$ARGUMENTS[0]` (e.g., `\u002Famg-check-key-vault 3d`), adjust accordingly. For resource log queries, keep the range narrow (1-2 days) to avoid timeouts.\n\n---\n\n## Workflow\n\n### Phase 1: Validate Datasource & Discover Vaults\n\n**Step 1a: Validate Datasource**\n\nCall `amgmcp_datasource_list` with no parameters.\n\nSearch the results for a datasource with `type` equal to `grafana-azure-monitor-datasource`. Extract its `uid`.\n\n- If it matches the configured UID, proceed.\n- If it differs, update `memory\u002Famg-check-key-vault\u002Fconfig.md`, warn the user, and use the new UID.\n- If no Azure Monitor datasource is found, abort with a clear error.\n\n**Step 1b: Discover All Key Vaults**\n\nCall `amgmcp_query_resource_graph` once using the configured datasource UID and subscription ID(s):\n\n```\nazureMonitorDatasourceUid: {DATASOURCE_UID}\nquery: |\n  resources\n  | where type == 'microsoft.keyvault\u002Fvaults'\n  | where subscriptionId in ({SUBSCRIPTION_IDS})\n  | project name, resourceGroup, location, subscriptionId, sku=properties.sku.name, enableSoftDelete=properties.enableSoftDelete, enablePurgeProtection=properties.enablePurgeProtection, provisioningState=properties.provisioningState\n  | order by location asc, name asc\n```\n\nReplace `{SUBSCRIPTION_IDS}` with the configured subscription IDs formatted as comma-separated quoted strings (e.g., `'sub-id-1', 'sub-id-2'`).\n\n**Constructing the ARM resource ID**: Use subscriptionId from each row:\n\n```\n\u002Fsubscriptions\u002F{subscriptionId}\u002FresourceGroups\u002F{resourceGroup}\u002Fproviders\u002FMicrosoft.KeyVault\u002Fvaults\u002F{name}\n```\n\n**Region summary**: Derive from the vault list by counting vaults per unique `location` value.\n\n**SKU summary**: Count vaults by `sku` (standard vs premium).\n\nNote any vaults not in \"Succeeded\" provisioning state — flag them immediately.\n\nIf zero vaults are found, report \"No Key Vaults found\" and stop.\n\n### Phase 2: Fleet-Wide Pulse Check\n\nCall `amgmcp_pulse_check` once to get a summary across all key vaults:\n\n```\nazureMonitorDatasourceUid: {DATASOURCE_UID}\npastDays: 7\nscenarios: keyvault_summary\n```\n\nIf `$1` provides a subscription ID, add `subscriptionId` to scope the scan. Otherwise, if the config has a single subscription, pass it.\n\n**After the pulse check, verify:**\n1. The number of scanned resources is close to the Phase 1 vault count.\n2. The scenario shows `status: \"completed\"`.\n3. If errors occurred, retry once. If still failing, note the failure in the report.\n\n**Cross-reference pulse check results with Phase 1 inventory** to enrich each vault with its resource group, region, and SKU from the Resource Graph data.\n\n### Phase 3: Top 7 Deep Dive\n\nFrom the pulse check results, **select at most 7 vaults** for detailed investigation. Prioritize vaults with the most interesting signals:\n\n1. **Availability drops** — any vault below 99.9% availability\n2. **Highest error counts** — vaults with the most non-Success responses (especially 401, 403, 429)\n3. **Highest latency** — vaults with the highest average API latency\n4. **Throttling (429)** — vaults showing rate-limiting responses\n5. **Diversity** — prefer selecting vaults from different regions to maximize coverage\n\nIf the pulse check shows fewer than 7 vaults with notable signals, only deep-dive those that have something worth investigating. Do not pad to 7.\n\nIf the pulse check shows the entire fleet is healthy with no notable signals, skip Phase 3 entirely and report the fleet as healthy.\n\n#### Step 3a: Deep Metrics\n\nFor each selected vault, query these metrics **in parallel** using `amgmcp_query_resource_metric`. Compute `from` (matching `pastDays` from Phase 2) and `to` (now) in ISO 8601 UTC.\n\n| Metric Name | Aggregation | Interval | Purpose |\n|-------------|-------------|----------|---------|\n| `Availability` | `Average` | PT6H | Availability trend |\n| `ServiceApiLatency` | `Average` | PT6H | Average API latency |\n| `ServiceApiLatency` | `Maximum` | PT6H | Tail latency spikes |\n| `ServiceApiHit` | `Total` | PT6H | Total API call volume |\n| `ServiceApiResult` (errors) | `Total` | PT6H | Error count (`filter: StatusCode ne '200'`) |\n| `ServiceApiResult` (throttled) | `Total` | PT6H | Throttling count (`filter: StatusCode eq '429'`) |\n| `ServiceApiResult` (auth failures) | `Total` | PT6H | Auth errors (`filter: StatusCode eq '401' or StatusCode eq '403'`) |\n| `SaturationShoebox` | `Average` | PT6H | Vault capacity saturation |\n\nAll 7 vaults can be queried in parallel (7 vaults x 8 metrics = 56 calls, within the 30-call batch cap when split into 2 batches).\n\n**Correlation analysis** — when analyzing metrics together:\n- **High latency + high API hits** = vault under load, possibly approaching throttle limits\n- **High latency + throttling (429)** = vault is being rate-limited, clients retrying\n- **High errors + normal latency** = client-side issues (bad auth, missing secrets)\n- **High 401\u002F403 + specific time window** = key rotation event or misconfigured client\n- **Availability drop + high errors** = sustained vault issue\n- **High saturation + high API hits** = vault approaching transaction limits\n- **Dormant (all empty)** = no traffic, investigate if orphaned\n\n#### Step 3b: Resource Logs\n\nFor each selected vault, query Key Vault resource logs using `amgmcp_query_resource_log`. Keep time range to 1-2 days.\n\n**Log Query 1: Failed requests by status code**\n```kql\nAzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d >= 400\n| summarize count() by httpStatusCode_d, OperationName, bin(TimeGenerated, 1h)\n| order by TimeGenerated asc\n```\n\n**Log Query 2: Top error operations**\n```kql\nAzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d >= 400\n| summarize count() by OperationName, httpStatusCode_d, ResultSignature\n| order by count_ desc\n| take 30\n```\n\n**Log Query 3: Throttled requests (429) over time**\n```kql\nAzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d == 429\n| summarize count() by OperationName, bin(TimeGenerated, 1h)\n| order by TimeGenerated asc\n```\n\n**Log Query 4: Request volume trend**\n```kql\nAzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| summarize\n    TotalRequests=count(),\n    FailedRequests=countif(httpStatusCode_d >= 400),\n    ThrottledRequests=countif(httpStatusCode_d == 429),\n    AvgDurationMs=round(avg(DurationMs), 2)\n    by bin(TimeGenerated, 1h)\n| order by TimeGenerated asc\n```\n\n**Log Query 5: Authentication failures**\n```kql\nAzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d in (401, 403)\n| summarize count() by OperationName, CallerIPAddress, identity_claim_appid_g\n| order by count_ desc\n| take 20\n```\n\n> **Note**: If `AzureDiagnostics` with `ResourceType == \"VAULTS\"` returns no data, diagnostic settings may not be configured. Note it and skip logs for that vault.\n\n---\n\n## Classification\n\n| Severity | Criteria |\n|----------|----------|\n| **CRITICAL** | Availability avg \u003C 99.0%, OR SaturationShoebox avg > 75% |\n| **WARNING** | Availability avg \u003C 99.9%, OR ServiceApiLatency avg > 200ms, OR sustained 429 throttling across multiple time windows, OR sustained 401\u002F403 errors |\n| **DORMANT** | All metrics return empty timeSeries (no traffic in scan period) |\n| **HEALTHY** | All metrics within normal ranges |\n\n---\n\n## Analysis Guidance\n\nFor known patterns, deep-dive queries, and correlation techniques, see [reference\u002Fanalysis-patterns.md](${CLAUDE_SKILL_DIR}\u002Freference\u002Fanalysis-patterns.md).\n\nFor optional deep-dive queries, see [reference\u002Fdeep-dive-queries.md](${CLAUDE_SKILL_DIR}\u002Freference\u002Fdeep-dive-queries.md).\n\n---\n\n## Output Format\n\nPresent a summary report with these sections:\n\n### 1. Fleet Inventory\n\nVault count by region, subscription, and SKU. Flag any vaults not in \"Succeeded\" provisioning state. Note soft-delete and purge-protection status.\n\n### 2. Pulse Check Summary\n\nFleet-wide summary from the `keyvault_summary` pulse check:\n- Total vaults scanned and scan status\n- Key fleet-wide metrics (availability, latency, API hits, error counts)\n- Breakdown by health status (healthy \u002F warning \u002F critical \u002F dormant)\n- Which vaults were selected for deep dive and why each was chosen\n\n### 3. Deep Dive Findings (Top 7)\n\nFor each selected vault:\n- **Metric timeline**: Availability, API latency, API hits, saturation over the scan window\n- **Anomaly characterization**: spike vs sustained, onset time, duration, recovery\n- **Correlation analysis**: which metrics moved together\n- **Error rate**: error results \u002F total API hits percentage\n\n### 4. Resource Log Findings\n\nFor each deep-dived vault:\n- **Error summary**: top error status codes, affected operations, throttling timeline\n- **Latency analysis**: slow operations by type\n- **Authentication failures**: if any, source IPs and application IDs\n\n### 5. Known Issue Cross-Reference\n\nCompare findings against `memory\u002Famg-check-key-vault\u002Freport.md`. For each known bug, state: still active \u002F improving \u002F worsening \u002F resolved.\n\n### 6. Action Items\n\nPrioritized list:\n- **Critical**: vaults with availability \u003C 99.0% or saturation > 75%\n- **High**: vaults with sustained throttling (429), high latency, or auth failures\n- **Medium**: vaults with elevated latency, intermittent errors, or approaching saturation\n- **Low**: dormant vaults (investigate if orphaned), informational items\n\n---\n\n## Update Known Issues\n\nAfter presenting findings, update `memory\u002Famg-check-key-vault\u002Freport.md`:\n\n1. **Read the current file** (create if it doesn't exist).\n2. **Update status** of existing bugs based on today's telemetry.\n3. **Add new bugs** with: severity, vault name, region, metric evidence, log evidence, root cause, recommended action.\n4. **Update the \"Updated\" date** in the header.\n\nOnly add genuine issues: sustained availability drops, persistent throttling, high error rates, or latency degradation.\n\n---\n\n## Error Handling\n\nSee **[${CLAUDE_SKILL_DIR}\u002Freference\u002Ferror-handling.md](${CLAUDE_SKILL_DIR}\u002Freference\u002Ferror-handling.md)** for the full recovery table.\n\n---\n\n## Reference\n\n- Key Vault resource type: `Microsoft.KeyVault\u002Fvaults`\n- ARM ID template: `\u002Fsubscriptions\u002F{SUB}\u002FresourceGroups\u002F{RG}\u002Fproviders\u002FMicrosoft.KeyVault\u002Fvaults\u002F{name}`\n- Resource log table: `AzureDiagnostics` (with `ResourceType == \"VAULTS\"`)\n- Key status codes: `429` (throttled), `401` (unauthorized), `403` (forbidden), `404` (not found)\n- Key metrics: `Availability`, `ServiceApiHit`, `ServiceApiLatency`, `ServiceApiResult`, `SaturationShoebox`\n- Known issues: `memory\u002Famg-check-key-vault\u002Freport.md`\n- Configuration: `memory\u002Famg-check-key-vault\u002Fconfig.md`\n\n---\n\n## First-Run Setup\n\nRun only when Config shows `NOT_CONFIGURED`. After completing, return to the [Workflow](#workflow) above.\n\n**1. Discover Datasource UID**: Call `amgmcp_datasource_list`. Filter `type == \"grafana-azure-monitor-datasource\"`. Prefer `uid == \"azure-monitor-oob\"` if multiple match. Abort if zero match.\n\n**2. Discover Subscription ID(s)**: Run this Resource Graph query to list all subscriptions with key vaults, then present the results as a table and ask the user which subscription(s) to use:\n```\nresources\n| where type == 'microsoft.keyvault\u002Fvaults'\n| join kind=inner (\n    resourcecontainers\n    | where type == 'microsoft.resources\u002Fsubscriptions'\n    | project subscriptionId, subscriptionName=name\n) on subscriptionId\n| summarize KeyVaults=count() by subscriptionId, subscriptionName\n| order by KeyVaults desc\n```\n\nPresent the results as a table with columns: **Subscription Name**, **Subscription ID**, **Key Vaults**. Then ask the user: *\"Which subscription ID(s) should I configure for this health check?\"*\n\n**3. Write config**: Write `memory\u002Famg-check-key-vault\u002Fconfig.md`:\n```markdown\n# amg-check-key-vault Configuration\n\nUser-specific values for the Key Vault health check skill.\nThis file is auto-generated on first run and can be edited manually.\n\n## Azure Monitor Datasource\n- **UID**: {discovered_uid}\n- **Name**: {discovered_name}\n\n## Subscriptions\n- {subscription_id_1}\n- {subscription_id_2}\n```\n\n**4. Confirm**: Show the resolved config and ask for confirmation before proceeding.\n",{"data":35,"body":40},{"name":4,"description":6,"argument-hint":36,"disable-model-invocation":37,"effort":38,"allowed-tools":39},"[time-range, e.g. 7d, 1d, 3d] [subscription-id]",true,"max","mcp__amg__amgmcp_pulse_check mcp__amg__amgmcp_query_resource_graph mcp__amg__amgmcp_query_resource_metric mcp__amg__amgmcp_query_resource_metric_definition mcp__amg__amgmcp_query_resource_log mcp__amg__amgmcp_datasource_list mcp__amg__amgmcp_query_activity_log Bash(node *) Glob Read Write Edit",{"type":41,"children":42},"root",[43,52,96,120,127,154,160,227,233,254,260,285,303,387,393,422,426,432,439,447,460,488,514,522,534,546,567,577,586,604,622,627,632,638,649,658,678,686,712,722,728,740,793,798,803,810,852,1151,1156,1166,1239,1245,1258,1266,1330,1338,1398,1406,1457,1465,1551,1559,1618,1647,1650,1656,1742,1745,1751,1763,1775,1778,1784,1789,1795,1800,1806,1819,1842,1848,1853,1895,1901,1906,1939,1945,1957,1963,1968,2011,2014,2020,2032,2075,2080,2083,2089,2105,2108,2114,2248,2251,2256,2275,2308,2318,2327,2357,2373,2541,2551],{"type":44,"tag":45,"props":46,"children":48},"element","h2",{"id":47},"runtime-context",[49],{"type":50,"value":51},"text","Runtime Context",{"type":44,"tag":53,"props":54,"children":55},"ul",{},[56,69,80,91],{"type":44,"tag":57,"props":58,"children":59},"li",{},[60,62],{"type":50,"value":61},"Current UTC time: !",{"type":44,"tag":63,"props":64,"children":66},"code",{"className":65},[],[67],{"type":50,"value":68},"date -u +%Y-%m-%dT%H:%M:%SZ",{"type":44,"tag":57,"props":70,"children":71},{},[72,74],{"type":50,"value":73},"Config: !",{"type":44,"tag":63,"props":75,"children":77},{"className":76},[],[78],{"type":50,"value":79},"cat memory\u002Famg-check-key-vault\u002Fconfig.md 2>\u002Fdev\u002Fnull || echo \"NOT_CONFIGURED\"",{"type":44,"tag":57,"props":81,"children":82},{},[83,85],{"type":50,"value":84},"Prior report: !",{"type":44,"tag":63,"props":86,"children":88},{"className":87},[],[89],{"type":50,"value":90},"[ -f memory\u002Famg-check-key-vault\u002Freport.md ] && echo \"exists ($(grep -c '^### KV-' memory\u002Famg-check-key-vault\u002Freport.md) bugs documented)\" || echo \"not found\"",{"type":44,"tag":57,"props":92,"children":93},{},[94],{"type":50,"value":95},"Arguments: time-range=$0, subscription-override=$1",{"type":44,"tag":97,"props":98,"children":99},"blockquote",{},[100],{"type":44,"tag":101,"props":102,"children":103},"p",{},[104,110,112,118],{"type":44,"tag":105,"props":106,"children":107},"strong",{},[108],{"type":50,"value":109},"Known Issues",{"type":50,"value":111},": Before presenting findings, cross-reference results against ",{"type":44,"tag":63,"props":113,"children":115},{"className":114},[],[116],{"type":50,"value":117},"memory\u002Famg-check-key-vault\u002Freport.md",{"type":50,"value":119},".",{"type":44,"tag":121,"props":122,"children":124},"h1",{"id":123},"azure-key-vault-health-check",[125],{"type":50,"value":126},"Azure Key Vault Health Check",{"type":44,"tag":101,"props":128,"children":129},{},[130,132,137,139,145,147,152],{"type":50,"value":131},"Analyze Azure Key Vault health using a ",{"type":44,"tag":105,"props":133,"children":134},{},[135],{"type":50,"value":136},"two-phase approach",{"type":50,"value":138},": a single ",{"type":44,"tag":63,"props":140,"children":142},{"className":141},[],[143],{"type":50,"value":144},"amgmcp_pulse_check",{"type":50,"value":146}," call for fleet-wide summary, followed by targeted deep dives into the ",{"type":44,"tag":105,"props":148,"children":149},{},[150],{"type":50,"value":151},"top 7 most interesting vaults",{"type":50,"value":153}," only.",{"type":44,"tag":45,"props":155,"children":157},{"id":156},"critical-constraints",[158],{"type":50,"value":159},"Critical Constraints",{"type":44,"tag":53,"props":161,"children":162},{},[163,173,183,217],{"type":44,"tag":57,"props":164,"children":165},{},[166,171],{"type":44,"tag":105,"props":167,"children":168},{},[169],{"type":50,"value":170},"Do NOT use subagents (Agent tool) for MCP queries.",{"type":50,"value":172}," Subagents do not have access to MCP tools. All MCP tool calls must be made directly from the main conversation context.",{"type":44,"tag":57,"props":174,"children":175},{},[176,181],{"type":44,"tag":105,"props":177,"children":178},{},[179],{"type":50,"value":180},"Deep dive limit: at most 7 vaults.",{"type":50,"value":182}," Select the most interesting vaults from pulse check results. Do not deep-dive the entire fleet.",{"type":44,"tag":57,"props":184,"children":185},{},[186,191,193,199,201,207,209,215],{"type":44,"tag":105,"props":187,"children":188},{},[189],{"type":50,"value":190},"Time format",{"type":50,"value":192},": ISO 8601 UTC with explicit ",{"type":44,"tag":63,"props":194,"children":196},{"className":195},[],[197],{"type":50,"value":198},"from",{"type":50,"value":200},"\u002F",{"type":44,"tag":63,"props":202,"children":204},{"className":203},[],[205],{"type":50,"value":206},"to",{"type":50,"value":208}," — NEVER use ",{"type":44,"tag":63,"props":210,"children":212},{"className":211},[],[213],{"type":50,"value":214},"timespan",{"type":50,"value":216}," (it causes errors).",{"type":44,"tag":57,"props":218,"children":219},{},[220,225],{"type":44,"tag":105,"props":221,"children":222},{},[223],{"type":50,"value":224},"Parallelism cap",{"type":50,"value":226},": 30 concurrent MCP calls per batch. Reduce to 4-5 if rate-limited.",{"type":44,"tag":45,"props":228,"children":230},{"id":229},"prerequisites",[231],{"type":50,"value":232},"Prerequisites",{"type":44,"tag":53,"props":234,"children":235},{},[236,249],{"type":44,"tag":57,"props":237,"children":238},{},[239,241,247],{"type":50,"value":240},"An AMG-MCP server must be connected (the ",{"type":44,"tag":63,"props":242,"children":244},{"className":243},[],[245],{"type":50,"value":246},"allowed-tools",{"type":50,"value":248}," frontmatter references the MCP server name — update it if your server has a different name)",{"type":44,"tag":57,"props":250,"children":251},{},[252],{"type":50,"value":253},"The MCP server's Grafana service account token environment variable must be set",{"type":44,"tag":45,"props":255,"children":257},{"id":256},"configuration",[258],{"type":50,"value":259},"Configuration",{"type":44,"tag":101,"props":261,"children":262},{},[263,274,276,283],{"type":44,"tag":105,"props":264,"children":265},{},[266,268],{"type":50,"value":267},"If Config shows ",{"type":44,"tag":63,"props":269,"children":271},{"className":270},[],[272],{"type":50,"value":273},"NOT_CONFIGURED",{"type":50,"value":275},": Run ",{"type":44,"tag":277,"props":278,"children":280},"a",{"href":279},"#first-run-setup",[281],{"type":50,"value":282},"First-Run Setup",{"type":50,"value":284}," at the bottom of this file, then return here.",{"type":44,"tag":101,"props":286,"children":287},{},[288,293,295,301],{"type":44,"tag":105,"props":289,"children":290},{},[291],{"type":50,"value":292},"If Config is populated",{"type":50,"value":294},": Extract the datasource UID and subscription ID(s) from the pre-loaded Runtime Context above and use them for all queries. Use ",{"type":44,"tag":63,"props":296,"children":298},{"className":297},[],[299],{"type":50,"value":300},"$1",{"type":50,"value":302}," as the subscription override if provided.",{"type":44,"tag":53,"props":304,"children":305},{},[306,330,354,372],{"type":44,"tag":57,"props":307,"children":308},{},[309,314,316,322,324],{"type":44,"tag":105,"props":310,"children":311},{},[312],{"type":50,"value":313},"Datasource UID",{"type":50,"value":315},": from ",{"type":44,"tag":63,"props":317,"children":319},{"className":318},[],[320],{"type":50,"value":321},"## Azure Monitor Datasource",{"type":50,"value":323}," > ",{"type":44,"tag":63,"props":325,"children":327},{"className":326},[],[328],{"type":50,"value":329},"UID",{"type":44,"tag":57,"props":331,"children":332},{},[333,338,339,345,347,352],{"type":44,"tag":105,"props":334,"children":335},{},[336],{"type":50,"value":337},"Subscription ID(s)",{"type":50,"value":315},{"type":44,"tag":63,"props":340,"children":342},{"className":341},[],[343],{"type":50,"value":344},"## Subscriptions",{"type":50,"value":346}," (or ",{"type":44,"tag":63,"props":348,"children":350},{"className":349},[],[351],{"type":50,"value":300},{"type":50,"value":353}," if provided)",{"type":44,"tag":57,"props":355,"children":356},{},[357,362,364,370],{"type":44,"tag":105,"props":358,"children":359},{},[360],{"type":50,"value":361},"Resource Type",{"type":50,"value":363},": ",{"type":44,"tag":63,"props":365,"children":367},{"className":366},[],[368],{"type":50,"value":369},"microsoft.keyvault\u002Fvaults",{"type":50,"value":371}," (lowercase)",{"type":44,"tag":57,"props":373,"children":374},{},[375,380,381],{"type":44,"tag":105,"props":376,"children":377},{},[378],{"type":50,"value":379},"ARM ID template",{"type":50,"value":363},{"type":44,"tag":63,"props":382,"children":384},{"className":383},[],[385],{"type":50,"value":386},"\u002Fsubscriptions\u002F{SUB}\u002FresourceGroups\u002F{RG}\u002Fproviders\u002FMicrosoft.KeyVault\u002Fvaults\u002F{name}",{"type":44,"tag":45,"props":388,"children":390},{"id":389},"time-range",[391],{"type":50,"value":392},"Time Range",{"type":44,"tag":101,"props":394,"children":395},{},[396,398,404,406,412,414,420],{"type":50,"value":397},"Default is 7 days (",{"type":44,"tag":63,"props":399,"children":401},{"className":400},[],[402],{"type":50,"value":403},"pastDays: 7",{"type":50,"value":405},") for pulse check and deep-dive metrics, 24 hours for resource logs. If the user specifies a different range via ",{"type":44,"tag":63,"props":407,"children":409},{"className":408},[],[410],{"type":50,"value":411},"$ARGUMENTS[0]",{"type":50,"value":413}," (e.g., ",{"type":44,"tag":63,"props":415,"children":417},{"className":416},[],[418],{"type":50,"value":419},"\u002Famg-check-key-vault 3d",{"type":50,"value":421},"), adjust accordingly. For resource log queries, keep the range narrow (1-2 days) to avoid timeouts.",{"type":44,"tag":423,"props":424,"children":425},"hr",{},[],{"type":44,"tag":45,"props":427,"children":429},{"id":428},"workflow",[430],{"type":50,"value":431},"Workflow",{"type":44,"tag":433,"props":434,"children":436},"h3",{"id":435},"phase-1-validate-datasource-discover-vaults",[437],{"type":50,"value":438},"Phase 1: Validate Datasource & Discover Vaults",{"type":44,"tag":101,"props":440,"children":441},{},[442],{"type":44,"tag":105,"props":443,"children":444},{},[445],{"type":50,"value":446},"Step 1a: Validate Datasource",{"type":44,"tag":101,"props":448,"children":449},{},[450,452,458],{"type":50,"value":451},"Call ",{"type":44,"tag":63,"props":453,"children":455},{"className":454},[],[456],{"type":50,"value":457},"amgmcp_datasource_list",{"type":50,"value":459}," with no parameters.",{"type":44,"tag":101,"props":461,"children":462},{},[463,465,471,473,479,481,487],{"type":50,"value":464},"Search the results for a datasource with ",{"type":44,"tag":63,"props":466,"children":468},{"className":467},[],[469],{"type":50,"value":470},"type",{"type":50,"value":472}," equal to ",{"type":44,"tag":63,"props":474,"children":476},{"className":475},[],[477],{"type":50,"value":478},"grafana-azure-monitor-datasource",{"type":50,"value":480},". Extract its ",{"type":44,"tag":63,"props":482,"children":484},{"className":483},[],[485],{"type":50,"value":486},"uid",{"type":50,"value":119},{"type":44,"tag":53,"props":489,"children":490},{},[491,496,509],{"type":44,"tag":57,"props":492,"children":493},{},[494],{"type":50,"value":495},"If it matches the configured UID, proceed.",{"type":44,"tag":57,"props":497,"children":498},{},[499,501,507],{"type":50,"value":500},"If it differs, update ",{"type":44,"tag":63,"props":502,"children":504},{"className":503},[],[505],{"type":50,"value":506},"memory\u002Famg-check-key-vault\u002Fconfig.md",{"type":50,"value":508},", warn the user, and use the new UID.",{"type":44,"tag":57,"props":510,"children":511},{},[512],{"type":50,"value":513},"If no Azure Monitor datasource is found, abort with a clear error.",{"type":44,"tag":101,"props":515,"children":516},{},[517],{"type":44,"tag":105,"props":518,"children":519},{},[520],{"type":50,"value":521},"Step 1b: Discover All Key Vaults",{"type":44,"tag":101,"props":523,"children":524},{},[525,526,532],{"type":50,"value":451},{"type":44,"tag":63,"props":527,"children":529},{"className":528},[],[530],{"type":50,"value":531},"amgmcp_query_resource_graph",{"type":50,"value":533}," once using the configured datasource UID and subscription ID(s):",{"type":44,"tag":535,"props":536,"children":540},"pre",{"className":537,"code":539,"language":50},[538],"language-text","azureMonitorDatasourceUid: {DATASOURCE_UID}\nquery: |\n  resources\n  | where type == 'microsoft.keyvault\u002Fvaults'\n  | where subscriptionId in ({SUBSCRIPTION_IDS})\n  | project name, resourceGroup, location, subscriptionId, sku=properties.sku.name, enableSoftDelete=properties.enableSoftDelete, enablePurgeProtection=properties.enablePurgeProtection, provisioningState=properties.provisioningState\n  | order by location asc, name asc\n",[541],{"type":44,"tag":63,"props":542,"children":544},{"__ignoreMap":543},"",[545],{"type":50,"value":539},{"type":44,"tag":101,"props":547,"children":548},{},[549,551,557,559,565],{"type":50,"value":550},"Replace ",{"type":44,"tag":63,"props":552,"children":554},{"className":553},[],[555],{"type":50,"value":556},"{SUBSCRIPTION_IDS}",{"type":50,"value":558}," with the configured subscription IDs formatted as comma-separated quoted strings (e.g., ",{"type":44,"tag":63,"props":560,"children":562},{"className":561},[],[563],{"type":50,"value":564},"'sub-id-1', 'sub-id-2'",{"type":50,"value":566},").",{"type":44,"tag":101,"props":568,"children":569},{},[570,575],{"type":44,"tag":105,"props":571,"children":572},{},[573],{"type":50,"value":574},"Constructing the ARM resource ID",{"type":50,"value":576},": Use subscriptionId from each row:",{"type":44,"tag":535,"props":578,"children":581},{"className":579,"code":580,"language":50},[538],"\u002Fsubscriptions\u002F{subscriptionId}\u002FresourceGroups\u002F{resourceGroup}\u002Fproviders\u002FMicrosoft.KeyVault\u002Fvaults\u002F{name}\n",[582],{"type":44,"tag":63,"props":583,"children":584},{"__ignoreMap":543},[585],{"type":50,"value":580},{"type":44,"tag":101,"props":587,"children":588},{},[589,594,596,602],{"type":44,"tag":105,"props":590,"children":591},{},[592],{"type":50,"value":593},"Region summary",{"type":50,"value":595},": Derive from the vault list by counting vaults per unique ",{"type":44,"tag":63,"props":597,"children":599},{"className":598},[],[600],{"type":50,"value":601},"location",{"type":50,"value":603}," value.",{"type":44,"tag":101,"props":605,"children":606},{},[607,612,614,620],{"type":44,"tag":105,"props":608,"children":609},{},[610],{"type":50,"value":611},"SKU summary",{"type":50,"value":613},": Count vaults by ",{"type":44,"tag":63,"props":615,"children":617},{"className":616},[],[618],{"type":50,"value":619},"sku",{"type":50,"value":621}," (standard vs premium).",{"type":44,"tag":101,"props":623,"children":624},{},[625],{"type":50,"value":626},"Note any vaults not in \"Succeeded\" provisioning state — flag them immediately.",{"type":44,"tag":101,"props":628,"children":629},{},[630],{"type":50,"value":631},"If zero vaults are found, report \"No Key Vaults found\" and stop.",{"type":44,"tag":433,"props":633,"children":635},{"id":634},"phase-2-fleet-wide-pulse-check",[636],{"type":50,"value":637},"Phase 2: Fleet-Wide Pulse Check",{"type":44,"tag":101,"props":639,"children":640},{},[641,642,647],{"type":50,"value":451},{"type":44,"tag":63,"props":643,"children":645},{"className":644},[],[646],{"type":50,"value":144},{"type":50,"value":648}," once to get a summary across all key vaults:",{"type":44,"tag":535,"props":650,"children":653},{"className":651,"code":652,"language":50},[538],"azureMonitorDatasourceUid: {DATASOURCE_UID}\npastDays: 7\nscenarios: keyvault_summary\n",[654],{"type":44,"tag":63,"props":655,"children":656},{"__ignoreMap":543},[657],{"type":50,"value":652},{"type":44,"tag":101,"props":659,"children":660},{},[661,663,668,670,676],{"type":50,"value":662},"If ",{"type":44,"tag":63,"props":664,"children":666},{"className":665},[],[667],{"type":50,"value":300},{"type":50,"value":669}," provides a subscription ID, add ",{"type":44,"tag":63,"props":671,"children":673},{"className":672},[],[674],{"type":50,"value":675},"subscriptionId",{"type":50,"value":677}," to scope the scan. Otherwise, if the config has a single subscription, pass it.",{"type":44,"tag":101,"props":679,"children":680},{},[681],{"type":44,"tag":105,"props":682,"children":683},{},[684],{"type":50,"value":685},"After the pulse check, verify:",{"type":44,"tag":687,"props":688,"children":689},"ol",{},[690,695,707],{"type":44,"tag":57,"props":691,"children":692},{},[693],{"type":50,"value":694},"The number of scanned resources is close to the Phase 1 vault count.",{"type":44,"tag":57,"props":696,"children":697},{},[698,700,706],{"type":50,"value":699},"The scenario shows ",{"type":44,"tag":63,"props":701,"children":703},{"className":702},[],[704],{"type":50,"value":705},"status: \"completed\"",{"type":50,"value":119},{"type":44,"tag":57,"props":708,"children":709},{},[710],{"type":50,"value":711},"If errors occurred, retry once. If still failing, note the failure in the report.",{"type":44,"tag":101,"props":713,"children":714},{},[715,720],{"type":44,"tag":105,"props":716,"children":717},{},[718],{"type":50,"value":719},"Cross-reference pulse check results with Phase 1 inventory",{"type":50,"value":721}," to enrich each vault with its resource group, region, and SKU from the Resource Graph data.",{"type":44,"tag":433,"props":723,"children":725},{"id":724},"phase-3-top-7-deep-dive",[726],{"type":50,"value":727},"Phase 3: Top 7 Deep Dive",{"type":44,"tag":101,"props":729,"children":730},{},[731,733,738],{"type":50,"value":732},"From the pulse check results, ",{"type":44,"tag":105,"props":734,"children":735},{},[736],{"type":50,"value":737},"select at most 7 vaults",{"type":50,"value":739}," for detailed investigation. Prioritize vaults with the most interesting signals:",{"type":44,"tag":687,"props":741,"children":742},{},[743,753,763,773,783],{"type":44,"tag":57,"props":744,"children":745},{},[746,751],{"type":44,"tag":105,"props":747,"children":748},{},[749],{"type":50,"value":750},"Availability drops",{"type":50,"value":752}," — any vault below 99.9% availability",{"type":44,"tag":57,"props":754,"children":755},{},[756,761],{"type":44,"tag":105,"props":757,"children":758},{},[759],{"type":50,"value":760},"Highest error counts",{"type":50,"value":762}," — vaults with the most non-Success responses (especially 401, 403, 429)",{"type":44,"tag":57,"props":764,"children":765},{},[766,771],{"type":44,"tag":105,"props":767,"children":768},{},[769],{"type":50,"value":770},"Highest latency",{"type":50,"value":772}," — vaults with the highest average API latency",{"type":44,"tag":57,"props":774,"children":775},{},[776,781],{"type":44,"tag":105,"props":777,"children":778},{},[779],{"type":50,"value":780},"Throttling (429)",{"type":50,"value":782}," — vaults showing rate-limiting responses",{"type":44,"tag":57,"props":784,"children":785},{},[786,791],{"type":44,"tag":105,"props":787,"children":788},{},[789],{"type":50,"value":790},"Diversity",{"type":50,"value":792}," — prefer selecting vaults from different regions to maximize coverage",{"type":44,"tag":101,"props":794,"children":795},{},[796],{"type":50,"value":797},"If the pulse check shows fewer than 7 vaults with notable signals, only deep-dive those that have something worth investigating. Do not pad to 7.",{"type":44,"tag":101,"props":799,"children":800},{},[801],{"type":50,"value":802},"If the pulse check shows the entire fleet is healthy with no notable signals, skip Phase 3 entirely and report the fleet as healthy.",{"type":44,"tag":804,"props":805,"children":807},"h4",{"id":806},"step-3a-deep-metrics",[808],{"type":50,"value":809},"Step 3a: Deep Metrics",{"type":44,"tag":101,"props":811,"children":812},{},[813,815,820,822,828,830,835,837,843,845,850],{"type":50,"value":814},"For each selected vault, query these metrics ",{"type":44,"tag":105,"props":816,"children":817},{},[818],{"type":50,"value":819},"in parallel",{"type":50,"value":821}," using ",{"type":44,"tag":63,"props":823,"children":825},{"className":824},[],[826],{"type":50,"value":827},"amgmcp_query_resource_metric",{"type":50,"value":829},". Compute ",{"type":44,"tag":63,"props":831,"children":833},{"className":832},[],[834],{"type":50,"value":198},{"type":50,"value":836}," (matching ",{"type":44,"tag":63,"props":838,"children":840},{"className":839},[],[841],{"type":50,"value":842},"pastDays",{"type":50,"value":844}," from Phase 2) and ",{"type":44,"tag":63,"props":846,"children":848},{"className":847},[],[849],{"type":50,"value":206},{"type":50,"value":851}," (now) in ISO 8601 UTC.",{"type":44,"tag":853,"props":854,"children":855},"table",{},[856,885],{"type":44,"tag":857,"props":858,"children":859},"thead",{},[860],{"type":44,"tag":861,"props":862,"children":863},"tr",{},[864,870,875,880],{"type":44,"tag":865,"props":866,"children":867},"th",{},[868],{"type":50,"value":869},"Metric Name",{"type":44,"tag":865,"props":871,"children":872},{},[873],{"type":50,"value":874},"Aggregation",{"type":44,"tag":865,"props":876,"children":877},{},[878],{"type":50,"value":879},"Interval",{"type":44,"tag":865,"props":881,"children":882},{},[883],{"type":50,"value":884},"Purpose",{"type":44,"tag":886,"props":887,"children":888},"tbody",{},[889,921,950,979,1009,1048,1085,1122],{"type":44,"tag":861,"props":890,"children":891},{},[892,902,911,916],{"type":44,"tag":893,"props":894,"children":895},"td",{},[896],{"type":44,"tag":63,"props":897,"children":899},{"className":898},[],[900],{"type":50,"value":901},"Availability",{"type":44,"tag":893,"props":903,"children":904},{},[905],{"type":44,"tag":63,"props":906,"children":908},{"className":907},[],[909],{"type":50,"value":910},"Average",{"type":44,"tag":893,"props":912,"children":913},{},[914],{"type":50,"value":915},"PT6H",{"type":44,"tag":893,"props":917,"children":918},{},[919],{"type":50,"value":920},"Availability trend",{"type":44,"tag":861,"props":922,"children":923},{},[924,933,941,945],{"type":44,"tag":893,"props":925,"children":926},{},[927],{"type":44,"tag":63,"props":928,"children":930},{"className":929},[],[931],{"type":50,"value":932},"ServiceApiLatency",{"type":44,"tag":893,"props":934,"children":935},{},[936],{"type":44,"tag":63,"props":937,"children":939},{"className":938},[],[940],{"type":50,"value":910},{"type":44,"tag":893,"props":942,"children":943},{},[944],{"type":50,"value":915},{"type":44,"tag":893,"props":946,"children":947},{},[948],{"type":50,"value":949},"Average API latency",{"type":44,"tag":861,"props":951,"children":952},{},[953,961,970,974],{"type":44,"tag":893,"props":954,"children":955},{},[956],{"type":44,"tag":63,"props":957,"children":959},{"className":958},[],[960],{"type":50,"value":932},{"type":44,"tag":893,"props":962,"children":963},{},[964],{"type":44,"tag":63,"props":965,"children":967},{"className":966},[],[968],{"type":50,"value":969},"Maximum",{"type":44,"tag":893,"props":971,"children":972},{},[973],{"type":50,"value":915},{"type":44,"tag":893,"props":975,"children":976},{},[977],{"type":50,"value":978},"Tail latency spikes",{"type":44,"tag":861,"props":980,"children":981},{},[982,991,1000,1004],{"type":44,"tag":893,"props":983,"children":984},{},[985],{"type":44,"tag":63,"props":986,"children":988},{"className":987},[],[989],{"type":50,"value":990},"ServiceApiHit",{"type":44,"tag":893,"props":992,"children":993},{},[994],{"type":44,"tag":63,"props":995,"children":997},{"className":996},[],[998],{"type":50,"value":999},"Total",{"type":44,"tag":893,"props":1001,"children":1002},{},[1003],{"type":50,"value":915},{"type":44,"tag":893,"props":1005,"children":1006},{},[1007],{"type":50,"value":1008},"Total API call volume",{"type":44,"tag":861,"props":1010,"children":1011},{},[1012,1023,1031,1035],{"type":44,"tag":893,"props":1013,"children":1014},{},[1015,1021],{"type":44,"tag":63,"props":1016,"children":1018},{"className":1017},[],[1019],{"type":50,"value":1020},"ServiceApiResult",{"type":50,"value":1022}," (errors)",{"type":44,"tag":893,"props":1024,"children":1025},{},[1026],{"type":44,"tag":63,"props":1027,"children":1029},{"className":1028},[],[1030],{"type":50,"value":999},{"type":44,"tag":893,"props":1032,"children":1033},{},[1034],{"type":50,"value":915},{"type":44,"tag":893,"props":1036,"children":1037},{},[1038,1040,1046],{"type":50,"value":1039},"Error count (",{"type":44,"tag":63,"props":1041,"children":1043},{"className":1042},[],[1044],{"type":50,"value":1045},"filter: StatusCode ne '200'",{"type":50,"value":1047},")",{"type":44,"tag":861,"props":1049,"children":1050},{},[1051,1061,1069,1073],{"type":44,"tag":893,"props":1052,"children":1053},{},[1054,1059],{"type":44,"tag":63,"props":1055,"children":1057},{"className":1056},[],[1058],{"type":50,"value":1020},{"type":50,"value":1060}," (throttled)",{"type":44,"tag":893,"props":1062,"children":1063},{},[1064],{"type":44,"tag":63,"props":1065,"children":1067},{"className":1066},[],[1068],{"type":50,"value":999},{"type":44,"tag":893,"props":1070,"children":1071},{},[1072],{"type":50,"value":915},{"type":44,"tag":893,"props":1074,"children":1075},{},[1076,1078,1084],{"type":50,"value":1077},"Throttling count (",{"type":44,"tag":63,"props":1079,"children":1081},{"className":1080},[],[1082],{"type":50,"value":1083},"filter: StatusCode eq '429'",{"type":50,"value":1047},{"type":44,"tag":861,"props":1086,"children":1087},{},[1088,1098,1106,1110],{"type":44,"tag":893,"props":1089,"children":1090},{},[1091,1096],{"type":44,"tag":63,"props":1092,"children":1094},{"className":1093},[],[1095],{"type":50,"value":1020},{"type":50,"value":1097}," (auth failures)",{"type":44,"tag":893,"props":1099,"children":1100},{},[1101],{"type":44,"tag":63,"props":1102,"children":1104},{"className":1103},[],[1105],{"type":50,"value":999},{"type":44,"tag":893,"props":1107,"children":1108},{},[1109],{"type":50,"value":915},{"type":44,"tag":893,"props":1111,"children":1112},{},[1113,1115,1121],{"type":50,"value":1114},"Auth errors (",{"type":44,"tag":63,"props":1116,"children":1118},{"className":1117},[],[1119],{"type":50,"value":1120},"filter: StatusCode eq '401' or StatusCode eq '403'",{"type":50,"value":1047},{"type":44,"tag":861,"props":1123,"children":1124},{},[1125,1134,1142,1146],{"type":44,"tag":893,"props":1126,"children":1127},{},[1128],{"type":44,"tag":63,"props":1129,"children":1131},{"className":1130},[],[1132],{"type":50,"value":1133},"SaturationShoebox",{"type":44,"tag":893,"props":1135,"children":1136},{},[1137],{"type":44,"tag":63,"props":1138,"children":1140},{"className":1139},[],[1141],{"type":50,"value":910},{"type":44,"tag":893,"props":1143,"children":1144},{},[1145],{"type":50,"value":915},{"type":44,"tag":893,"props":1147,"children":1148},{},[1149],{"type":50,"value":1150},"Vault capacity saturation",{"type":44,"tag":101,"props":1152,"children":1153},{},[1154],{"type":50,"value":1155},"All 7 vaults can be queried in parallel (7 vaults x 8 metrics = 56 calls, within the 30-call batch cap when split into 2 batches).",{"type":44,"tag":101,"props":1157,"children":1158},{},[1159,1164],{"type":44,"tag":105,"props":1160,"children":1161},{},[1162],{"type":50,"value":1163},"Correlation analysis",{"type":50,"value":1165}," — when analyzing metrics together:",{"type":44,"tag":53,"props":1167,"children":1168},{},[1169,1179,1189,1199,1209,1219,1229],{"type":44,"tag":57,"props":1170,"children":1171},{},[1172,1177],{"type":44,"tag":105,"props":1173,"children":1174},{},[1175],{"type":50,"value":1176},"High latency + high API hits",{"type":50,"value":1178}," = vault under load, possibly approaching throttle limits",{"type":44,"tag":57,"props":1180,"children":1181},{},[1182,1187],{"type":44,"tag":105,"props":1183,"children":1184},{},[1185],{"type":50,"value":1186},"High latency + throttling (429)",{"type":50,"value":1188}," = vault is being rate-limited, clients retrying",{"type":44,"tag":57,"props":1190,"children":1191},{},[1192,1197],{"type":44,"tag":105,"props":1193,"children":1194},{},[1195],{"type":50,"value":1196},"High errors + normal latency",{"type":50,"value":1198}," = client-side issues (bad auth, missing secrets)",{"type":44,"tag":57,"props":1200,"children":1201},{},[1202,1207],{"type":44,"tag":105,"props":1203,"children":1204},{},[1205],{"type":50,"value":1206},"High 401\u002F403 + specific time window",{"type":50,"value":1208}," = key rotation event or misconfigured client",{"type":44,"tag":57,"props":1210,"children":1211},{},[1212,1217],{"type":44,"tag":105,"props":1213,"children":1214},{},[1215],{"type":50,"value":1216},"Availability drop + high errors",{"type":50,"value":1218}," = sustained vault issue",{"type":44,"tag":57,"props":1220,"children":1221},{},[1222,1227],{"type":44,"tag":105,"props":1223,"children":1224},{},[1225],{"type":50,"value":1226},"High saturation + high API hits",{"type":50,"value":1228}," = vault approaching transaction limits",{"type":44,"tag":57,"props":1230,"children":1231},{},[1232,1237],{"type":44,"tag":105,"props":1233,"children":1234},{},[1235],{"type":50,"value":1236},"Dormant (all empty)",{"type":50,"value":1238}," = no traffic, investigate if orphaned",{"type":44,"tag":804,"props":1240,"children":1242},{"id":1241},"step-3b-resource-logs",[1243],{"type":50,"value":1244},"Step 3b: Resource Logs",{"type":44,"tag":101,"props":1246,"children":1247},{},[1248,1250,1256],{"type":50,"value":1249},"For each selected vault, query Key Vault resource logs using ",{"type":44,"tag":63,"props":1251,"children":1253},{"className":1252},[],[1254],{"type":50,"value":1255},"amgmcp_query_resource_log",{"type":50,"value":1257},". Keep time range to 1-2 days.",{"type":44,"tag":101,"props":1259,"children":1260},{},[1261],{"type":44,"tag":105,"props":1262,"children":1263},{},[1264],{"type":50,"value":1265},"Log Query 1: Failed requests by status code",{"type":44,"tag":535,"props":1267,"children":1271},{"className":1268,"code":1269,"language":1270,"meta":543,"style":543},"language-kql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","AzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d >= 400\n| summarize count() by httpStatusCode_d, OperationName, bin(TimeGenerated, 1h)\n| order by TimeGenerated asc\n","kql",[1272],{"type":44,"tag":63,"props":1273,"children":1274},{"__ignoreMap":543},[1275,1286,1294,1303,1312,1321],{"type":44,"tag":1276,"props":1277,"children":1280},"span",{"class":1278,"line":1279},"line",1,[1281],{"type":44,"tag":1276,"props":1282,"children":1283},{},[1284],{"type":50,"value":1285},"AzureDiagnostics\n",{"type":44,"tag":1276,"props":1287,"children":1288},{"class":1278,"line":24},[1289],{"type":44,"tag":1276,"props":1290,"children":1291},{},[1292],{"type":50,"value":1293},"| where ResourceType == \"VAULTS\"\n",{"type":44,"tag":1276,"props":1295,"children":1297},{"class":1278,"line":1296},3,[1298],{"type":44,"tag":1276,"props":1299,"children":1300},{},[1301],{"type":50,"value":1302},"| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n",{"type":44,"tag":1276,"props":1304,"children":1306},{"class":1278,"line":1305},4,[1307],{"type":44,"tag":1276,"props":1308,"children":1309},{},[1310],{"type":50,"value":1311},"| where httpStatusCode_d >= 400\n",{"type":44,"tag":1276,"props":1313,"children":1315},{"class":1278,"line":1314},5,[1316],{"type":44,"tag":1276,"props":1317,"children":1318},{},[1319],{"type":50,"value":1320},"| summarize count() by httpStatusCode_d, OperationName, bin(TimeGenerated, 1h)\n",{"type":44,"tag":1276,"props":1322,"children":1324},{"class":1278,"line":1323},6,[1325],{"type":44,"tag":1276,"props":1326,"children":1327},{},[1328],{"type":50,"value":1329},"| order by TimeGenerated asc\n",{"type":44,"tag":101,"props":1331,"children":1332},{},[1333],{"type":44,"tag":105,"props":1334,"children":1335},{},[1336],{"type":50,"value":1337},"Log Query 2: Top error operations",{"type":44,"tag":535,"props":1339,"children":1341},{"className":1268,"code":1340,"language":1270,"meta":543,"style":543},"AzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d >= 400\n| summarize count() by OperationName, httpStatusCode_d, ResultSignature\n| order by count_ desc\n| take 30\n",[1342],{"type":44,"tag":63,"props":1343,"children":1344},{"__ignoreMap":543},[1345,1352,1359,1366,1373,1381,1389],{"type":44,"tag":1276,"props":1346,"children":1347},{"class":1278,"line":1279},[1348],{"type":44,"tag":1276,"props":1349,"children":1350},{},[1351],{"type":50,"value":1285},{"type":44,"tag":1276,"props":1353,"children":1354},{"class":1278,"line":24},[1355],{"type":44,"tag":1276,"props":1356,"children":1357},{},[1358],{"type":50,"value":1293},{"type":44,"tag":1276,"props":1360,"children":1361},{"class":1278,"line":1296},[1362],{"type":44,"tag":1276,"props":1363,"children":1364},{},[1365],{"type":50,"value":1302},{"type":44,"tag":1276,"props":1367,"children":1368},{"class":1278,"line":1305},[1369],{"type":44,"tag":1276,"props":1370,"children":1371},{},[1372],{"type":50,"value":1311},{"type":44,"tag":1276,"props":1374,"children":1375},{"class":1278,"line":1314},[1376],{"type":44,"tag":1276,"props":1377,"children":1378},{},[1379],{"type":50,"value":1380},"| summarize count() by OperationName, httpStatusCode_d, ResultSignature\n",{"type":44,"tag":1276,"props":1382,"children":1383},{"class":1278,"line":1323},[1384],{"type":44,"tag":1276,"props":1385,"children":1386},{},[1387],{"type":50,"value":1388},"| order by count_ desc\n",{"type":44,"tag":1276,"props":1390,"children":1392},{"class":1278,"line":1391},7,[1393],{"type":44,"tag":1276,"props":1394,"children":1395},{},[1396],{"type":50,"value":1397},"| take 30\n",{"type":44,"tag":101,"props":1399,"children":1400},{},[1401],{"type":44,"tag":105,"props":1402,"children":1403},{},[1404],{"type":50,"value":1405},"Log Query 3: Throttled requests (429) over time",{"type":44,"tag":535,"props":1407,"children":1409},{"className":1268,"code":1408,"language":1270,"meta":543,"style":543},"AzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d == 429\n| summarize count() by OperationName, bin(TimeGenerated, 1h)\n| order by TimeGenerated asc\n",[1410],{"type":44,"tag":63,"props":1411,"children":1412},{"__ignoreMap":543},[1413,1420,1427,1434,1442,1450],{"type":44,"tag":1276,"props":1414,"children":1415},{"class":1278,"line":1279},[1416],{"type":44,"tag":1276,"props":1417,"children":1418},{},[1419],{"type":50,"value":1285},{"type":44,"tag":1276,"props":1421,"children":1422},{"class":1278,"line":24},[1423],{"type":44,"tag":1276,"props":1424,"children":1425},{},[1426],{"type":50,"value":1293},{"type":44,"tag":1276,"props":1428,"children":1429},{"class":1278,"line":1296},[1430],{"type":44,"tag":1276,"props":1431,"children":1432},{},[1433],{"type":50,"value":1302},{"type":44,"tag":1276,"props":1435,"children":1436},{"class":1278,"line":1305},[1437],{"type":44,"tag":1276,"props":1438,"children":1439},{},[1440],{"type":50,"value":1441},"| where httpStatusCode_d == 429\n",{"type":44,"tag":1276,"props":1443,"children":1444},{"class":1278,"line":1314},[1445],{"type":44,"tag":1276,"props":1446,"children":1447},{},[1448],{"type":50,"value":1449},"| summarize count() by OperationName, bin(TimeGenerated, 1h)\n",{"type":44,"tag":1276,"props":1451,"children":1452},{"class":1278,"line":1323},[1453],{"type":44,"tag":1276,"props":1454,"children":1455},{},[1456],{"type":50,"value":1329},{"type":44,"tag":101,"props":1458,"children":1459},{},[1460],{"type":44,"tag":105,"props":1461,"children":1462},{},[1463],{"type":50,"value":1464},"Log Query 4: Request volume trend",{"type":44,"tag":535,"props":1466,"children":1468},{"className":1268,"code":1467,"language":1270,"meta":543,"style":543},"AzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| summarize\n    TotalRequests=count(),\n    FailedRequests=countif(httpStatusCode_d >= 400),\n    ThrottledRequests=countif(httpStatusCode_d == 429),\n    AvgDurationMs=round(avg(DurationMs), 2)\n    by bin(TimeGenerated, 1h)\n| order by TimeGenerated asc\n",[1469],{"type":44,"tag":63,"props":1470,"children":1471},{"__ignoreMap":543},[1472,1479,1486,1493,1501,1509,1517,1525,1534,1543],{"type":44,"tag":1276,"props":1473,"children":1474},{"class":1278,"line":1279},[1475],{"type":44,"tag":1276,"props":1476,"children":1477},{},[1478],{"type":50,"value":1285},{"type":44,"tag":1276,"props":1480,"children":1481},{"class":1278,"line":24},[1482],{"type":44,"tag":1276,"props":1483,"children":1484},{},[1485],{"type":50,"value":1293},{"type":44,"tag":1276,"props":1487,"children":1488},{"class":1278,"line":1296},[1489],{"type":44,"tag":1276,"props":1490,"children":1491},{},[1492],{"type":50,"value":1302},{"type":44,"tag":1276,"props":1494,"children":1495},{"class":1278,"line":1305},[1496],{"type":44,"tag":1276,"props":1497,"children":1498},{},[1499],{"type":50,"value":1500},"| summarize\n",{"type":44,"tag":1276,"props":1502,"children":1503},{"class":1278,"line":1314},[1504],{"type":44,"tag":1276,"props":1505,"children":1506},{},[1507],{"type":50,"value":1508},"    TotalRequests=count(),\n",{"type":44,"tag":1276,"props":1510,"children":1511},{"class":1278,"line":1323},[1512],{"type":44,"tag":1276,"props":1513,"children":1514},{},[1515],{"type":50,"value":1516},"    FailedRequests=countif(httpStatusCode_d >= 400),\n",{"type":44,"tag":1276,"props":1518,"children":1519},{"class":1278,"line":1391},[1520],{"type":44,"tag":1276,"props":1521,"children":1522},{},[1523],{"type":50,"value":1524},"    ThrottledRequests=countif(httpStatusCode_d == 429),\n",{"type":44,"tag":1276,"props":1526,"children":1528},{"class":1278,"line":1527},8,[1529],{"type":44,"tag":1276,"props":1530,"children":1531},{},[1532],{"type":50,"value":1533},"    AvgDurationMs=round(avg(DurationMs), 2)\n",{"type":44,"tag":1276,"props":1535,"children":1537},{"class":1278,"line":1536},9,[1538],{"type":44,"tag":1276,"props":1539,"children":1540},{},[1541],{"type":50,"value":1542},"    by bin(TimeGenerated, 1h)\n",{"type":44,"tag":1276,"props":1544,"children":1546},{"class":1278,"line":1545},10,[1547],{"type":44,"tag":1276,"props":1548,"children":1549},{},[1550],{"type":50,"value":1329},{"type":44,"tag":101,"props":1552,"children":1553},{},[1554],{"type":44,"tag":105,"props":1555,"children":1556},{},[1557],{"type":50,"value":1558},"Log Query 5: Authentication failures",{"type":44,"tag":535,"props":1560,"children":1562},{"className":1268,"code":1561,"language":1270,"meta":543,"style":543},"AzureDiagnostics\n| where ResourceType == \"VAULTS\"\n| where TimeGenerated between (datetime(\u003CSTART>) .. datetime(\u003CEND>))\n| where httpStatusCode_d in (401, 403)\n| summarize count() by OperationName, CallerIPAddress, identity_claim_appid_g\n| order by count_ desc\n| take 20\n",[1563],{"type":44,"tag":63,"props":1564,"children":1565},{"__ignoreMap":543},[1566,1573,1580,1587,1595,1603,1610],{"type":44,"tag":1276,"props":1567,"children":1568},{"class":1278,"line":1279},[1569],{"type":44,"tag":1276,"props":1570,"children":1571},{},[1572],{"type":50,"value":1285},{"type":44,"tag":1276,"props":1574,"children":1575},{"class":1278,"line":24},[1576],{"type":44,"tag":1276,"props":1577,"children":1578},{},[1579],{"type":50,"value":1293},{"type":44,"tag":1276,"props":1581,"children":1582},{"class":1278,"line":1296},[1583],{"type":44,"tag":1276,"props":1584,"children":1585},{},[1586],{"type":50,"value":1302},{"type":44,"tag":1276,"props":1588,"children":1589},{"class":1278,"line":1305},[1590],{"type":44,"tag":1276,"props":1591,"children":1592},{},[1593],{"type":50,"value":1594},"| where httpStatusCode_d in (401, 403)\n",{"type":44,"tag":1276,"props":1596,"children":1597},{"class":1278,"line":1314},[1598],{"type":44,"tag":1276,"props":1599,"children":1600},{},[1601],{"type":50,"value":1602},"| summarize count() by OperationName, CallerIPAddress, identity_claim_appid_g\n",{"type":44,"tag":1276,"props":1604,"children":1605},{"class":1278,"line":1323},[1606],{"type":44,"tag":1276,"props":1607,"children":1608},{},[1609],{"type":50,"value":1388},{"type":44,"tag":1276,"props":1611,"children":1612},{"class":1278,"line":1391},[1613],{"type":44,"tag":1276,"props":1614,"children":1615},{},[1616],{"type":50,"value":1617},"| take 20\n",{"type":44,"tag":97,"props":1619,"children":1620},{},[1621],{"type":44,"tag":101,"props":1622,"children":1623},{},[1624,1629,1631,1637,1639,1645],{"type":44,"tag":105,"props":1625,"children":1626},{},[1627],{"type":50,"value":1628},"Note",{"type":50,"value":1630},": If ",{"type":44,"tag":63,"props":1632,"children":1634},{"className":1633},[],[1635],{"type":50,"value":1636},"AzureDiagnostics",{"type":50,"value":1638}," with ",{"type":44,"tag":63,"props":1640,"children":1642},{"className":1641},[],[1643],{"type":50,"value":1644},"ResourceType == \"VAULTS\"",{"type":50,"value":1646}," returns no data, diagnostic settings may not be configured. Note it and skip logs for that vault.",{"type":44,"tag":423,"props":1648,"children":1649},{},[],{"type":44,"tag":45,"props":1651,"children":1653},{"id":1652},"classification",[1654],{"type":50,"value":1655},"Classification",{"type":44,"tag":853,"props":1657,"children":1658},{},[1659,1675],{"type":44,"tag":857,"props":1660,"children":1661},{},[1662],{"type":44,"tag":861,"props":1663,"children":1664},{},[1665,1670],{"type":44,"tag":865,"props":1666,"children":1667},{},[1668],{"type":50,"value":1669},"Severity",{"type":44,"tag":865,"props":1671,"children":1672},{},[1673],{"type":50,"value":1674},"Criteria",{"type":44,"tag":886,"props":1676,"children":1677},{},[1678,1694,1710,1726],{"type":44,"tag":861,"props":1679,"children":1680},{},[1681,1689],{"type":44,"tag":893,"props":1682,"children":1683},{},[1684],{"type":44,"tag":105,"props":1685,"children":1686},{},[1687],{"type":50,"value":1688},"CRITICAL",{"type":44,"tag":893,"props":1690,"children":1691},{},[1692],{"type":50,"value":1693},"Availability avg \u003C 99.0%, OR SaturationShoebox avg > 75%",{"type":44,"tag":861,"props":1695,"children":1696},{},[1697,1705],{"type":44,"tag":893,"props":1698,"children":1699},{},[1700],{"type":44,"tag":105,"props":1701,"children":1702},{},[1703],{"type":50,"value":1704},"WARNING",{"type":44,"tag":893,"props":1706,"children":1707},{},[1708],{"type":50,"value":1709},"Availability avg \u003C 99.9%, OR ServiceApiLatency avg > 200ms, OR sustained 429 throttling across multiple time windows, OR sustained 401\u002F403 errors",{"type":44,"tag":861,"props":1711,"children":1712},{},[1713,1721],{"type":44,"tag":893,"props":1714,"children":1715},{},[1716],{"type":44,"tag":105,"props":1717,"children":1718},{},[1719],{"type":50,"value":1720},"DORMANT",{"type":44,"tag":893,"props":1722,"children":1723},{},[1724],{"type":50,"value":1725},"All metrics return empty timeSeries (no traffic in scan period)",{"type":44,"tag":861,"props":1727,"children":1728},{},[1729,1737],{"type":44,"tag":893,"props":1730,"children":1731},{},[1732],{"type":44,"tag":105,"props":1733,"children":1734},{},[1735],{"type":50,"value":1736},"HEALTHY",{"type":44,"tag":893,"props":1738,"children":1739},{},[1740],{"type":50,"value":1741},"All metrics within normal ranges",{"type":44,"tag":423,"props":1743,"children":1744},{},[],{"type":44,"tag":45,"props":1746,"children":1748},{"id":1747},"analysis-guidance",[1749],{"type":50,"value":1750},"Analysis Guidance",{"type":44,"tag":101,"props":1752,"children":1753},{},[1754,1756,1762],{"type":50,"value":1755},"For known patterns, deep-dive queries, and correlation techniques, see ",{"type":44,"tag":277,"props":1757,"children":1759},{"href":1758},"$%7BCLAUDE_SKILL_DIR%7D\u002Freference\u002Fanalysis-patterns.md",[1760],{"type":50,"value":1761},"reference\u002Fanalysis-patterns.md",{"type":50,"value":119},{"type":44,"tag":101,"props":1764,"children":1765},{},[1766,1768,1774],{"type":50,"value":1767},"For optional deep-dive queries, see ",{"type":44,"tag":277,"props":1769,"children":1771},{"href":1770},"$%7BCLAUDE_SKILL_DIR%7D\u002Freference\u002Fdeep-dive-queries.md",[1772],{"type":50,"value":1773},"reference\u002Fdeep-dive-queries.md",{"type":50,"value":119},{"type":44,"tag":423,"props":1776,"children":1777},{},[],{"type":44,"tag":45,"props":1779,"children":1781},{"id":1780},"output-format",[1782],{"type":50,"value":1783},"Output Format",{"type":44,"tag":101,"props":1785,"children":1786},{},[1787],{"type":50,"value":1788},"Present a summary report with these sections:",{"type":44,"tag":433,"props":1790,"children":1792},{"id":1791},"_1-fleet-inventory",[1793],{"type":50,"value":1794},"1. Fleet Inventory",{"type":44,"tag":101,"props":1796,"children":1797},{},[1798],{"type":50,"value":1799},"Vault count by region, subscription, and SKU. Flag any vaults not in \"Succeeded\" provisioning state. Note soft-delete and purge-protection status.",{"type":44,"tag":433,"props":1801,"children":1803},{"id":1802},"_2-pulse-check-summary",[1804],{"type":50,"value":1805},"2. Pulse Check Summary",{"type":44,"tag":101,"props":1807,"children":1808},{},[1809,1811,1817],{"type":50,"value":1810},"Fleet-wide summary from the ",{"type":44,"tag":63,"props":1812,"children":1814},{"className":1813},[],[1815],{"type":50,"value":1816},"keyvault_summary",{"type":50,"value":1818}," pulse check:",{"type":44,"tag":53,"props":1820,"children":1821},{},[1822,1827,1832,1837],{"type":44,"tag":57,"props":1823,"children":1824},{},[1825],{"type":50,"value":1826},"Total vaults scanned and scan status",{"type":44,"tag":57,"props":1828,"children":1829},{},[1830],{"type":50,"value":1831},"Key fleet-wide metrics (availability, latency, API hits, error counts)",{"type":44,"tag":57,"props":1833,"children":1834},{},[1835],{"type":50,"value":1836},"Breakdown by health status (healthy \u002F warning \u002F critical \u002F dormant)",{"type":44,"tag":57,"props":1838,"children":1839},{},[1840],{"type":50,"value":1841},"Which vaults were selected for deep dive and why each was chosen",{"type":44,"tag":433,"props":1843,"children":1845},{"id":1844},"_3-deep-dive-findings-top-7",[1846],{"type":50,"value":1847},"3. Deep Dive Findings (Top 7)",{"type":44,"tag":101,"props":1849,"children":1850},{},[1851],{"type":50,"value":1852},"For each selected vault:",{"type":44,"tag":53,"props":1854,"children":1855},{},[1856,1866,1876,1885],{"type":44,"tag":57,"props":1857,"children":1858},{},[1859,1864],{"type":44,"tag":105,"props":1860,"children":1861},{},[1862],{"type":50,"value":1863},"Metric timeline",{"type":50,"value":1865},": Availability, API latency, API hits, saturation over the scan window",{"type":44,"tag":57,"props":1867,"children":1868},{},[1869,1874],{"type":44,"tag":105,"props":1870,"children":1871},{},[1872],{"type":50,"value":1873},"Anomaly characterization",{"type":50,"value":1875},": spike vs sustained, onset time, duration, recovery",{"type":44,"tag":57,"props":1877,"children":1878},{},[1879,1883],{"type":44,"tag":105,"props":1880,"children":1881},{},[1882],{"type":50,"value":1163},{"type":50,"value":1884},": which metrics moved together",{"type":44,"tag":57,"props":1886,"children":1887},{},[1888,1893],{"type":44,"tag":105,"props":1889,"children":1890},{},[1891],{"type":50,"value":1892},"Error rate",{"type":50,"value":1894},": error results \u002F total API hits percentage",{"type":44,"tag":433,"props":1896,"children":1898},{"id":1897},"_4-resource-log-findings",[1899],{"type":50,"value":1900},"4. Resource Log Findings",{"type":44,"tag":101,"props":1902,"children":1903},{},[1904],{"type":50,"value":1905},"For each deep-dived vault:",{"type":44,"tag":53,"props":1907,"children":1908},{},[1909,1919,1929],{"type":44,"tag":57,"props":1910,"children":1911},{},[1912,1917],{"type":44,"tag":105,"props":1913,"children":1914},{},[1915],{"type":50,"value":1916},"Error summary",{"type":50,"value":1918},": top error status codes, affected operations, throttling timeline",{"type":44,"tag":57,"props":1920,"children":1921},{},[1922,1927],{"type":44,"tag":105,"props":1923,"children":1924},{},[1925],{"type":50,"value":1926},"Latency analysis",{"type":50,"value":1928},": slow operations by type",{"type":44,"tag":57,"props":1930,"children":1931},{},[1932,1937],{"type":44,"tag":105,"props":1933,"children":1934},{},[1935],{"type":50,"value":1936},"Authentication failures",{"type":50,"value":1938},": if any, source IPs and application IDs",{"type":44,"tag":433,"props":1940,"children":1942},{"id":1941},"_5-known-issue-cross-reference",[1943],{"type":50,"value":1944},"5. Known Issue Cross-Reference",{"type":44,"tag":101,"props":1946,"children":1947},{},[1948,1950,1955],{"type":50,"value":1949},"Compare findings against ",{"type":44,"tag":63,"props":1951,"children":1953},{"className":1952},[],[1954],{"type":50,"value":117},{"type":50,"value":1956},". For each known bug, state: still active \u002F improving \u002F worsening \u002F resolved.",{"type":44,"tag":433,"props":1958,"children":1960},{"id":1959},"_6-action-items",[1961],{"type":50,"value":1962},"6. Action Items",{"type":44,"tag":101,"props":1964,"children":1965},{},[1966],{"type":50,"value":1967},"Prioritized list:",{"type":44,"tag":53,"props":1969,"children":1970},{},[1971,1981,1991,2001],{"type":44,"tag":57,"props":1972,"children":1973},{},[1974,1979],{"type":44,"tag":105,"props":1975,"children":1976},{},[1977],{"type":50,"value":1978},"Critical",{"type":50,"value":1980},": vaults with availability \u003C 99.0% or saturation > 75%",{"type":44,"tag":57,"props":1982,"children":1983},{},[1984,1989],{"type":44,"tag":105,"props":1985,"children":1986},{},[1987],{"type":50,"value":1988},"High",{"type":50,"value":1990},": vaults with sustained throttling (429), high latency, or auth failures",{"type":44,"tag":57,"props":1992,"children":1993},{},[1994,1999],{"type":44,"tag":105,"props":1995,"children":1996},{},[1997],{"type":50,"value":1998},"Medium",{"type":50,"value":2000},": vaults with elevated latency, intermittent errors, or approaching saturation",{"type":44,"tag":57,"props":2002,"children":2003},{},[2004,2009],{"type":44,"tag":105,"props":2005,"children":2006},{},[2007],{"type":50,"value":2008},"Low",{"type":50,"value":2010},": dormant vaults (investigate if orphaned), informational items",{"type":44,"tag":423,"props":2012,"children":2013},{},[],{"type":44,"tag":45,"props":2015,"children":2017},{"id":2016},"update-known-issues",[2018],{"type":50,"value":2019},"Update Known Issues",{"type":44,"tag":101,"props":2021,"children":2022},{},[2023,2025,2030],{"type":50,"value":2024},"After presenting findings, update ",{"type":44,"tag":63,"props":2026,"children":2028},{"className":2027},[],[2029],{"type":50,"value":117},{"type":50,"value":2031},":",{"type":44,"tag":687,"props":2033,"children":2034},{},[2035,2045,2055,2065],{"type":44,"tag":57,"props":2036,"children":2037},{},[2038,2043],{"type":44,"tag":105,"props":2039,"children":2040},{},[2041],{"type":50,"value":2042},"Read the current file",{"type":50,"value":2044}," (create if it doesn't exist).",{"type":44,"tag":57,"props":2046,"children":2047},{},[2048,2053],{"type":44,"tag":105,"props":2049,"children":2050},{},[2051],{"type":50,"value":2052},"Update status",{"type":50,"value":2054}," of existing bugs based on today's telemetry.",{"type":44,"tag":57,"props":2056,"children":2057},{},[2058,2063],{"type":44,"tag":105,"props":2059,"children":2060},{},[2061],{"type":50,"value":2062},"Add new bugs",{"type":50,"value":2064}," with: severity, vault name, region, metric evidence, log evidence, root cause, recommended action.",{"type":44,"tag":57,"props":2066,"children":2067},{},[2068,2073],{"type":44,"tag":105,"props":2069,"children":2070},{},[2071],{"type":50,"value":2072},"Update the \"Updated\" date",{"type":50,"value":2074}," in the header.",{"type":44,"tag":101,"props":2076,"children":2077},{},[2078],{"type":50,"value":2079},"Only add genuine issues: sustained availability drops, persistent throttling, high error rates, or latency degradation.",{"type":44,"tag":423,"props":2081,"children":2082},{},[],{"type":44,"tag":45,"props":2084,"children":2086},{"id":2085},"error-handling",[2087],{"type":50,"value":2088},"Error Handling",{"type":44,"tag":101,"props":2090,"children":2091},{},[2092,2094,2103],{"type":50,"value":2093},"See ",{"type":44,"tag":105,"props":2095,"children":2096},{},[2097],{"type":44,"tag":277,"props":2098,"children":2100},{"href":2099},"$%7BCLAUDE_SKILL_DIR%7D\u002Freference\u002Ferror-handling.md",[2101],{"type":50,"value":2102},"${CLAUDE_SKILL_DIR}\u002Freference\u002Ferror-handling.md",{"type":50,"value":2104}," for the full recovery table.",{"type":44,"tag":423,"props":2106,"children":2107},{},[],{"type":44,"tag":45,"props":2109,"children":2111},{"id":2110},"reference",[2112],{"type":50,"value":2113},"Reference",{"type":44,"tag":53,"props":2115,"children":2116},{},[2117,2128,2138,2156,2193,2228,2238],{"type":44,"tag":57,"props":2118,"children":2119},{},[2120,2122],{"type":50,"value":2121},"Key Vault resource type: ",{"type":44,"tag":63,"props":2123,"children":2125},{"className":2124},[],[2126],{"type":50,"value":2127},"Microsoft.KeyVault\u002Fvaults",{"type":44,"tag":57,"props":2129,"children":2130},{},[2131,2133],{"type":50,"value":2132},"ARM ID template: ",{"type":44,"tag":63,"props":2134,"children":2136},{"className":2135},[],[2137],{"type":50,"value":386},{"type":44,"tag":57,"props":2139,"children":2140},{},[2141,2143,2148,2150,2155],{"type":50,"value":2142},"Resource log table: ",{"type":44,"tag":63,"props":2144,"children":2146},{"className":2145},[],[2147],{"type":50,"value":1636},{"type":50,"value":2149}," (with ",{"type":44,"tag":63,"props":2151,"children":2153},{"className":2152},[],[2154],{"type":50,"value":1644},{"type":50,"value":1047},{"type":44,"tag":57,"props":2157,"children":2158},{},[2159,2161,2167,2169,2175,2177,2183,2185,2191],{"type":50,"value":2160},"Key status codes: ",{"type":44,"tag":63,"props":2162,"children":2164},{"className":2163},[],[2165],{"type":50,"value":2166},"429",{"type":50,"value":2168}," (throttled), ",{"type":44,"tag":63,"props":2170,"children":2172},{"className":2171},[],[2173],{"type":50,"value":2174},"401",{"type":50,"value":2176}," (unauthorized), ",{"type":44,"tag":63,"props":2178,"children":2180},{"className":2179},[],[2181],{"type":50,"value":2182},"403",{"type":50,"value":2184}," (forbidden), ",{"type":44,"tag":63,"props":2186,"children":2188},{"className":2187},[],[2189],{"type":50,"value":2190},"404",{"type":50,"value":2192}," (not found)",{"type":44,"tag":57,"props":2194,"children":2195},{},[2196,2198,2203,2205,2210,2211,2216,2217,2222,2223],{"type":50,"value":2197},"Key metrics: ",{"type":44,"tag":63,"props":2199,"children":2201},{"className":2200},[],[2202],{"type":50,"value":901},{"type":50,"value":2204},", ",{"type":44,"tag":63,"props":2206,"children":2208},{"className":2207},[],[2209],{"type":50,"value":990},{"type":50,"value":2204},{"type":44,"tag":63,"props":2212,"children":2214},{"className":2213},[],[2215],{"type":50,"value":932},{"type":50,"value":2204},{"type":44,"tag":63,"props":2218,"children":2220},{"className":2219},[],[2221],{"type":50,"value":1020},{"type":50,"value":2204},{"type":44,"tag":63,"props":2224,"children":2226},{"className":2225},[],[2227],{"type":50,"value":1133},{"type":44,"tag":57,"props":2229,"children":2230},{},[2231,2233],{"type":50,"value":2232},"Known issues: ",{"type":44,"tag":63,"props":2234,"children":2236},{"className":2235},[],[2237],{"type":50,"value":117},{"type":44,"tag":57,"props":2239,"children":2240},{},[2241,2243],{"type":50,"value":2242},"Configuration: ",{"type":44,"tag":63,"props":2244,"children":2246},{"className":2245},[],[2247],{"type":50,"value":506},{"type":44,"tag":423,"props":2249,"children":2250},{},[],{"type":44,"tag":45,"props":2252,"children":2254},{"id":2253},"first-run-setup",[2255],{"type":50,"value":282},{"type":44,"tag":101,"props":2257,"children":2258},{},[2259,2261,2266,2268,2273],{"type":50,"value":2260},"Run only when Config shows ",{"type":44,"tag":63,"props":2262,"children":2264},{"className":2263},[],[2265],{"type":50,"value":273},{"type":50,"value":2267},". After completing, return to the ",{"type":44,"tag":277,"props":2269,"children":2271},{"href":2270},"#workflow",[2272],{"type":50,"value":431},{"type":50,"value":2274}," above.",{"type":44,"tag":101,"props":2276,"children":2277},{},[2278,2283,2285,2290,2292,2298,2300,2306],{"type":44,"tag":105,"props":2279,"children":2280},{},[2281],{"type":50,"value":2282},"1. Discover Datasource UID",{"type":50,"value":2284},": Call ",{"type":44,"tag":63,"props":2286,"children":2288},{"className":2287},[],[2289],{"type":50,"value":457},{"type":50,"value":2291},". Filter ",{"type":44,"tag":63,"props":2293,"children":2295},{"className":2294},[],[2296],{"type":50,"value":2297},"type == \"grafana-azure-monitor-datasource\"",{"type":50,"value":2299},". Prefer ",{"type":44,"tag":63,"props":2301,"children":2303},{"className":2302},[],[2304],{"type":50,"value":2305},"uid == \"azure-monitor-oob\"",{"type":50,"value":2307}," if multiple match. Abort if zero match.",{"type":44,"tag":101,"props":2309,"children":2310},{},[2311,2316],{"type":44,"tag":105,"props":2312,"children":2313},{},[2314],{"type":50,"value":2315},"2. Discover Subscription ID(s)",{"type":50,"value":2317},": Run this Resource Graph query to list all subscriptions with key vaults, then present the results as a table and ask the user which subscription(s) to use:",{"type":44,"tag":535,"props":2319,"children":2322},{"className":2320,"code":2321,"language":50},[538],"resources\n| where type == 'microsoft.keyvault\u002Fvaults'\n| join kind=inner (\n    resourcecontainers\n    | where type == 'microsoft.resources\u002Fsubscriptions'\n    | project subscriptionId, subscriptionName=name\n) on subscriptionId\n| summarize KeyVaults=count() by subscriptionId, subscriptionName\n| order by KeyVaults desc\n",[2323],{"type":44,"tag":63,"props":2324,"children":2325},{"__ignoreMap":543},[2326],{"type":50,"value":2321},{"type":44,"tag":101,"props":2328,"children":2329},{},[2330,2332,2337,2338,2343,2344,2349,2351],{"type":50,"value":2331},"Present the results as a table with columns: ",{"type":44,"tag":105,"props":2333,"children":2334},{},[2335],{"type":50,"value":2336},"Subscription Name",{"type":50,"value":2204},{"type":44,"tag":105,"props":2339,"children":2340},{},[2341],{"type":50,"value":2342},"Subscription ID",{"type":50,"value":2204},{"type":44,"tag":105,"props":2345,"children":2346},{},[2347],{"type":50,"value":2348},"Key Vaults",{"type":50,"value":2350},". Then ask the user: ",{"type":44,"tag":2352,"props":2353,"children":2354},"em",{},[2355],{"type":50,"value":2356},"\"Which subscription ID(s) should I configure for this health check?\"",{"type":44,"tag":101,"props":2358,"children":2359},{},[2360,2365,2367,2372],{"type":44,"tag":105,"props":2361,"children":2362},{},[2363],{"type":50,"value":2364},"3. Write config",{"type":50,"value":2366},": Write ",{"type":44,"tag":63,"props":2368,"children":2370},{"className":2369},[],[2371],{"type":50,"value":506},{"type":50,"value":2031},{"type":44,"tag":535,"props":2374,"children":2378},{"className":2375,"code":2376,"language":2377,"meta":543,"style":543},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# amg-check-key-vault Configuration\n\nUser-specific values for the Key Vault health check skill.\nThis file is auto-generated on first run and can be edited manually.\n\n## Azure Monitor Datasource\n- **UID**: {discovered_uid}\n- **Name**: {discovered_name}\n\n## Subscriptions\n- {subscription_id_1}\n- {subscription_id_2}\n","markdown",[2379],{"type":44,"tag":63,"props":2380,"children":2381},{"__ignoreMap":543},[2382,2397,2405,2414,2422,2429,2442,2471,2496,2503,2515,2528],{"type":44,"tag":1276,"props":2383,"children":2384},{"class":1278,"line":1279},[2385,2391],{"type":44,"tag":1276,"props":2386,"children":2388},{"style":2387},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[2389],{"type":50,"value":2390},"# ",{"type":44,"tag":1276,"props":2392,"children":2394},{"style":2393},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[2395],{"type":50,"value":2396},"amg-check-key-vault Configuration\n",{"type":44,"tag":1276,"props":2398,"children":2399},{"class":1278,"line":24},[2400],{"type":44,"tag":1276,"props":2401,"children":2402},{"emptyLinePlaceholder":37},[2403],{"type":50,"value":2404},"\n",{"type":44,"tag":1276,"props":2406,"children":2407},{"class":1278,"line":1296},[2408],{"type":44,"tag":1276,"props":2409,"children":2411},{"style":2410},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[2412],{"type":50,"value":2413},"User-specific values for the Key Vault health check skill.\n",{"type":44,"tag":1276,"props":2415,"children":2416},{"class":1278,"line":1305},[2417],{"type":44,"tag":1276,"props":2418,"children":2419},{"style":2410},[2420],{"type":50,"value":2421},"This file is auto-generated on first run and can be edited manually.\n",{"type":44,"tag":1276,"props":2423,"children":2424},{"class":1278,"line":1314},[2425],{"type":44,"tag":1276,"props":2426,"children":2427},{"emptyLinePlaceholder":37},[2428],{"type":50,"value":2404},{"type":44,"tag":1276,"props":2430,"children":2431},{"class":1278,"line":1323},[2432,2437],{"type":44,"tag":1276,"props":2433,"children":2434},{"style":2387},[2435],{"type":50,"value":2436},"## ",{"type":44,"tag":1276,"props":2438,"children":2439},{"style":2393},[2440],{"type":50,"value":2441},"Azure Monitor Datasource\n",{"type":44,"tag":1276,"props":2443,"children":2444},{"class":1278,"line":1391},[2445,2450,2456,2461,2466],{"type":44,"tag":1276,"props":2446,"children":2447},{"style":2387},[2448],{"type":50,"value":2449},"-",{"type":44,"tag":1276,"props":2451,"children":2453},{"style":2452},"--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#89DDFF;--shiki-default-font-weight:bold;--shiki-dark:#89DDFF;--shiki-dark-font-weight:bold",[2454],{"type":50,"value":2455}," **",{"type":44,"tag":1276,"props":2457,"children":2459},{"style":2458},"--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#F07178;--shiki-default-font-weight:bold;--shiki-dark:#F07178;--shiki-dark-font-weight:bold",[2460],{"type":50,"value":329},{"type":44,"tag":1276,"props":2462,"children":2463},{"style":2452},[2464],{"type":50,"value":2465},"**",{"type":44,"tag":1276,"props":2467,"children":2468},{"style":2410},[2469],{"type":50,"value":2470},": {discovered_uid}\n",{"type":44,"tag":1276,"props":2472,"children":2473},{"class":1278,"line":1527},[2474,2478,2482,2487,2491],{"type":44,"tag":1276,"props":2475,"children":2476},{"style":2387},[2477],{"type":50,"value":2449},{"type":44,"tag":1276,"props":2479,"children":2480},{"style":2452},[2481],{"type":50,"value":2455},{"type":44,"tag":1276,"props":2483,"children":2484},{"style":2458},[2485],{"type":50,"value":2486},"Name",{"type":44,"tag":1276,"props":2488,"children":2489},{"style":2452},[2490],{"type":50,"value":2465},{"type":44,"tag":1276,"props":2492,"children":2493},{"style":2410},[2494],{"type":50,"value":2495},": {discovered_name}\n",{"type":44,"tag":1276,"props":2497,"children":2498},{"class":1278,"line":1536},[2499],{"type":44,"tag":1276,"props":2500,"children":2501},{"emptyLinePlaceholder":37},[2502],{"type":50,"value":2404},{"type":44,"tag":1276,"props":2504,"children":2505},{"class":1278,"line":1545},[2506,2510],{"type":44,"tag":1276,"props":2507,"children":2508},{"style":2387},[2509],{"type":50,"value":2436},{"type":44,"tag":1276,"props":2511,"children":2512},{"style":2393},[2513],{"type":50,"value":2514},"Subscriptions\n",{"type":44,"tag":1276,"props":2516,"children":2518},{"class":1278,"line":2517},11,[2519,2523],{"type":44,"tag":1276,"props":2520,"children":2521},{"style":2387},[2522],{"type":50,"value":2449},{"type":44,"tag":1276,"props":2524,"children":2525},{"style":2410},[2526],{"type":50,"value":2527}," {subscription_id_1}\n",{"type":44,"tag":1276,"props":2529,"children":2531},{"class":1278,"line":2530},12,[2532,2536],{"type":44,"tag":1276,"props":2533,"children":2534},{"style":2387},[2535],{"type":50,"value":2449},{"type":44,"tag":1276,"props":2537,"children":2538},{"style":2410},[2539],{"type":50,"value":2540}," {subscription_id_2}\n",{"type":44,"tag":101,"props":2542,"children":2543},{},[2544,2549],{"type":44,"tag":105,"props":2545,"children":2546},{},[2547],{"type":50,"value":2548},"4. Confirm",{"type":50,"value":2550},": Show the resolved config and ask for confirmation before proceeding.",{"type":44,"tag":2552,"props":2553,"children":2554},"style",{},[2555],{"type":50,"value":2556},"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":2558,"total":1314},[2559,2576,2592,2599,2612],{"slug":2560,"name":2560,"fn":2561,"description":2562,"org":2563,"tags":2564,"stars":24,"repoUrl":25,"updatedAt":2575},"amg-check-azure-spend","analyze monthly Azure subscription costs","Monthly Azure subscription cost analysis — lists all accessible subscriptions, lets the user choose which to analyze, then queries last billing month's cost breakdown by resource type, region, and service category for each subscription. Queries subscriptions sequentially with 1-minute waits between calls to avoid billing API rate limits (429). On first run, auto-discovers datasource UID.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2565,2566,2569,2572],{"name":11,"slug":8,"type":16},{"name":2567,"slug":2568,"type":16},"Cost Optimization","cost-optimization",{"name":2570,"slug":2571,"type":16},"Finance","finance",{"name":2573,"slug":2574,"type":16},"Reporting","reporting","2026-07-12T08:19:59.033036",{"slug":2577,"name":2577,"fn":2578,"description":2579,"org":2580,"tags":2581,"stars":24,"repoUrl":25,"updatedAt":2591},"amg-check-cosmosdb-mongo-ru","monitor Cosmos DB for MongoDB health","Fleet-wide Cosmos DB for MongoDB (RU) health check — scans NormalizedRU consumption, service availability, server-side latency, throttling (429s), and replication metrics across all accounts, then deep-dives into abnormal accounts with resource logs and correlation analysis. Tracks known issues across sessions via persistent report. Uses AMG-MCP pulse check for Tier 1 triage, then batched Azure Monitor queries for Tier 2 investigation. On first run, auto-discovers datasource UID and prompts for subscription ID.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2582,2583,2586,2589,2590],{"name":11,"slug":8,"type":16},{"name":2584,"slug":2585,"type":16},"Cosmos DB","cosmos-db",{"name":2587,"slug":2588,"type":16},"MongoDB","mongodb",{"name":22,"slug":23,"type":16},{"name":18,"slug":19,"type":16},"2026-07-12T08:19:56.052424",{"slug":4,"name":4,"fn":5,"description":6,"org":2593,"tags":2594,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2595,2596,2597,2598],{"name":11,"slug":8,"type":16},{"name":22,"slug":23,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"slug":2600,"name":2600,"fn":2601,"description":2602,"org":2603,"tags":2604,"stars":24,"repoUrl":25,"updatedAt":2611},"amg-check-pg-flex","monitor PostgreSQL Flexible Server health","Fleet-wide PostgreSQL Flexible Server health check — scans CPU, memory, storage, IOPS, disk bandwidth, and connection metrics across all servers, then deep-dives into abnormal servers with resource logs and correlation analysis. Tracks known issues across sessions via persistent report. Uses AMG-MCP pulse check for Tier 1 triage, then batched Azure Monitor queries for Tier 2 investigation. On first run, auto-discovers datasource UID and prompts for subscription ID.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2605,2606,2607,2608],{"name":11,"slug":8,"type":16},{"name":22,"slug":23,"type":16},{"name":18,"slug":19,"type":16},{"name":2609,"slug":2610,"type":16},"PostgreSQL","postgresql","2026-07-12T08:19:54.767507",{"slug":2613,"name":2613,"fn":2614,"description":2615,"org":2616,"tags":2617,"stars":24,"repoUrl":25,"updatedAt":2626},"amg-check-storage-account","monitor Azure Storage Account health","Fleet-wide Azure Storage Account health check — pulse check for availability, latency, transactions, and error rates across all accounts, then deep-dives into the top 7 most interesting accounts with metrics (E2E latency, server latency, capacity, ingress\u002Fegress) and resource logs. Tracks known issues across sessions via persistent report. On first run, auto-discovers datasource UID and prompts for subscription ID.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2618,2619,2620,2623],{"name":11,"slug":8,"type":16},{"name":22,"slug":23,"type":16},{"name":2621,"slug":2622,"type":16},"Performance","performance",{"name":2624,"slug":2625,"type":16},"Storage","storage","2026-07-12T08:19:57.37917",{"items":2628,"total":2805},[2629,2648,2667,2686,2701,2716,2729,2744,2755,2767,2780,2793],{"slug":2630,"name":2630,"fn":2631,"description":2632,"org":2633,"tags":2634,"stars":2645,"repoUrl":2646,"updatedAt":2647},"azure-arg-external-evaluation-policy-author","author and test Azure Resource Graph policies","Use when the user wants to author, design, or test an Azure Policy that queries Azure Resource Graph (ARG) at request-time — i.e. a policy whose deny\u002Faudit decision depends on data from elsewhere in the subscription (sibling\u002Fparent resource state, RG-wide invariants, multi-hop relationships, etc.). Formally called Azure Policy External Evaluation; sometimes referred to colloquially as \"Invoke\". Drives an iterative KQL co-design loop against the user's real subscription via `az graph query`, then emits a policy definition, assignment, `.http` test flow, and an `EXPLANATION.md` companion. Read-only; never provisions anything.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2635,2636,2639,2642],{"name":11,"slug":8,"type":16},{"name":2637,"slug":2638,"type":16},"Compliance","compliance",{"name":2640,"slug":2641,"type":16},"Governance","governance",{"name":2643,"slug":2644,"type":16},"Policy","policy",1686,"https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-policy","2026-07-12T08:17:48.378432",{"slug":2649,"name":2649,"fn":2650,"description":2651,"org":2652,"tags":2653,"stars":2664,"repoUrl":2665,"updatedAt":2666},"azure-blueprints-migration","migrate Azure Blueprints to Template Specs","Use when a user needs to migrate off Azure Blueprints (definitions and\u002For assignments) to Template Specs and Deployment Stacks before the January 31, 2027 retirement. Covers inventory, export, conversion to Bicep, policy decoupling, Template Spec publishing, Deployment Stack deployment with deny-settings, validation, and cutover.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2654,2655,2658,2661],{"name":11,"slug":8,"type":16},{"name":2656,"slug":2657,"type":16},"Deployment","deployment",{"name":2659,"slug":2660,"type":16},"Infrastructure as Code","infrastructure-as-code",{"name":2662,"slug":2663,"type":16},"Migration","migration",260,"https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-blueprints","2026-07-12T08:17:49.646405",{"slug":2668,"name":2668,"fn":2669,"description":2670,"org":2671,"tags":2672,"stars":2683,"repoUrl":2684,"updatedAt":2685},"apiview-feedback-resolution","resolve APIView feedback on Azure SDKs","Analyze and resolve APIView review feedback on Azure SDK PRs. **UTILITY SKILL**. USE FOR: APIView comments, API review feedback, SDK API surface changes. DO NOT USE FOR: general code review, non-APIView feedback. INVOKES: azure-sdk-mcp:azsdk_apiview_get_comments, azure-sdk-mcp:azsdk_typespec_customized_code_update.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2673,2676,2677,2680],{"name":2674,"slug":2675,"type":16},"API Development","api-development",{"name":11,"slug":8,"type":16},{"name":2678,"slug":2679,"type":16},"Code Review","code-review",{"name":2681,"slug":2682,"type":16},"Documentation","documentation",133,"https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-tools","2026-07-12T08:17:43.350876",{"slug":2687,"name":2687,"fn":2688,"description":2689,"org":2690,"tags":2691,"stars":2683,"repoUrl":2684,"updatedAt":2700},"azsdk-common-live-and-recorded-tests","deploy resources and run Azure SDK tests","Deploy test resources and run Azure SDK tests in live, record, or playback mode. WHEN: \"run live tests\", \"run recorded tests\", \"deploy test resources\", \"record tests\", \"run tests in record mode\", \"clean up test resources\", \"run tests against live resources\". DO NOT USE FOR: writing new tests, authoring Bicep templates, playback-only test runs without resource deployment. INVOKES: azure-sdk-mcp:azsdk_package_run_tests.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2692,2693,2694,2697],{"name":11,"slug":8,"type":16},{"name":2656,"slug":2657,"type":16},{"name":2695,"slug":2696,"type":16},"SDK","sdk",{"name":2698,"slug":2699,"type":16},"Testing","testing","2026-07-12T08:17:44.718943",{"slug":2702,"name":2702,"fn":2703,"description":2704,"org":2705,"tags":2706,"stars":2683,"repoUrl":2684,"updatedAt":2715},"azsdk-common-prepare-release-plan","manage Azure SDK release plan work items","Create, get, update, abandon, and link SDK PRs to release plan work items for Azure SDK releases. **UTILITY SKILL**. USE FOR: \"create release plan\", \"get release plan\", \"update release plan\", \"update API spec in release plan\", \"update SDK details in release plan\", \"abandon release plan\", \"link SDK PR to plan\", \"namespace approval\", \"check release plan status\". DO NOT USE FOR: SDK code generation, pipeline troubleshooting, API review feedback. INVOKES: azure-sdk-mcp:azsdk_create_release_plan, azure-sdk-mcp:azsdk_get_release_plan, azure-sdk-mcp:azsdk_get_release_plan_for_spec_pr, azure-sdk-mcp:azsdk_update_release_plan, azure-sdk-mcp:azsdk_update_api_spec_pull_request_in_release_plan, azure-sdk-mcp:azsdk_update_sdk_details_in_release_plan, azure-sdk-mcp:azsdk_abandon_release_plan, azure-sdk-mcp:azsdk_link_sdk_pull_request_to_release_plan, azure-sdk-mcp:azsdk_link_namespace_approval_issue.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2707,2708,2711,2714],{"name":11,"slug":8,"type":16},{"name":2709,"slug":2710,"type":16},"GitHub","github",{"name":2712,"slug":2713,"type":16},"Project Management","project-management",{"name":2695,"slug":2696,"type":16},"2026-07-12T08:17:38.345387",{"slug":2717,"name":2717,"fn":2718,"description":2719,"org":2720,"tags":2721,"stars":2683,"repoUrl":2684,"updatedAt":2728},"azsdk-common-sdk-release","release Azure SDK packages","Check release readiness and trigger the release pipeline for Azure SDK packages. **UTILITY SKILL**. USE FOR: \"release SDK\", \"trigger release\", \"check release readiness\", \"release pipeline\", \"publish package\", \"ship SDK\". DO NOT USE FOR: SDK development, code generation, pipeline debugging, release plan creation. INVOKES: azure-sdk-mcp:azsdk_release_sdk.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2722,2723,2726,2727],{"name":11,"slug":8,"type":16},{"name":2724,"slug":2725,"type":16},"CI\u002FCD","ci-cd",{"name":2656,"slug":2657,"type":16},{"name":2695,"slug":2696,"type":16},"2026-07-12T08:17:34.27607",{"slug":2730,"name":2730,"fn":2731,"description":2732,"org":2733,"tags":2734,"stars":2683,"repoUrl":2684,"updatedAt":2743},"azure-typespec-author","author and modify Azure TypeSpec API specifications","Authors and modifies Azure TypeSpec (.tsp) API specifications. USE FOR: any TypeSpec\u002Ftsp change — api versions (add, bump, preview, stable, promote), resources, operations, models, properties, decorators, visibility, constraints, breaking changes, LRO, suppressions, operationId, spread model. Covers ARM resource-manager and data-plane services. DO NOT USE FOR: SDK generation, releasing SDK packages, or single MCP tool calls. INVOKES: azure-sdk-mcp:azsdk_typespec_generate_authoring_plan, azure-sdk-mcp:azsdk_run_typespec_validation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2735,2736,2737,2740],{"name":2674,"slug":2675,"type":16},{"name":11,"slug":8,"type":16},{"name":2738,"slug":2739,"type":16},"OpenAPI","openapi",{"name":2741,"slug":2742,"type":16},"Technical Writing","technical-writing","2026-07-12T08:17:39.603232",{"slug":2745,"name":2745,"fn":2746,"description":2747,"org":2748,"tags":2749,"stars":2683,"repoUrl":2684,"updatedAt":2754},"generate-sdk-locally","generate and test Azure SDKs locally","Generate, build, and test Azure SDKs locally from TypeSpec with automatic customization. WHEN: \"generate SDK locally\", \"build SDK\", \"run SDK tests\", \"run CI checks\", \"validate package\", \"run checks\", \"update changelog\", \"fix SDK build errors\", \"fix breaking changes\", \"resolve SDK generation errors\", \"customize TypeSpec\", \"rename SDK client\", \"rename SDK model\", \"hide operation from SDK\", \"fix analyzer errors\", \"resolve customization drift\", \"create subclient\", \"update metadata\", \"update version\". DO NOT USE FOR: publishing to package registries, CI pipeline configuration, API design review. INVOKES: azsdk_verify_setup, azsdk_package_generate_code, azsdk_package_build_code, azsdk_package_run_check, azsdk_package_run_tests, azsdk_customized_code_update, azsdk_package_update_changelog_content, azsdk_package_update_metadata, azsdk_package_update_version.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2750,2751,2752,2753],{"name":11,"slug":8,"type":16},{"name":2724,"slug":2725,"type":16},{"name":2695,"slug":2696,"type":16},{"name":2698,"slug":2699,"type":16},"2026-07-12T08:17:37.08523",{"slug":2756,"name":2756,"fn":2757,"description":2758,"org":2759,"tags":2760,"stars":2683,"repoUrl":2684,"updatedAt":2766},"markdown-token-optimizer","optimize markdown files for token efficiency","Analyze markdown files for token efficiency and reduce context-window bloat. **UTILITY SKILL**. DO NOT USE FOR: code optimization, general file editing, non-markdown files. TRIGGERS: optimize markdown, reduce tokens, token count, token bloat, too many tokens, make concise, shrink file, file too large, optimize for AI, token efficiency, verbose markdown, reduce file size. INVOKES: waza CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2761,2764,2765],{"name":2762,"slug":2763,"type":16},"LLM","llm",{"name":2621,"slug":2622,"type":16},{"name":2741,"slug":2742,"type":16},"2026-07-12T08:17:42.080413",{"slug":2768,"name":2768,"fn":2769,"description":2770,"org":2771,"tags":2772,"stars":2683,"repoUrl":2684,"updatedAt":2779},"pipeline-troubleshooting","troubleshoot Azure SDK CI pipelines","Diagnose and resolve failures in Azure SDK CI and generation pipelines. **UTILITY SKILL**. USE FOR: \"pipeline failed\", \"build failure\", \"CI check failing\", \"SDK generation error\", \"reproduce pipeline locally\", \"debug SDK pipeline\". DO NOT USE FOR: local build issues without pipeline context, API design review, SDK publishing. INVOKES: azure-sdk-mcp:azsdk_analyze_pipeline, azure-sdk-mcp:azsdk_package_build_code, azure-sdk-mcp:azsdk_package_run_check.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2773,2774,2775,2778],{"name":11,"slug":8,"type":16},{"name":2724,"slug":2725,"type":16},{"name":2776,"slug":2777,"type":16},"Debugging","debugging",{"name":2695,"slug":2696,"type":16},"2026-07-12T08:17:40.821512",{"slug":2781,"name":2781,"fn":2782,"description":2783,"org":2784,"tags":2785,"stars":2683,"repoUrl":2684,"updatedAt":2792},"sensei","improve skill frontmatter compliance","**WORKFLOW SKILL** — Iteratively improve skill frontmatter compliance using the Ralph loop pattern. WHEN: \"run sensei\", \"sensei help\", \"improve skill\", \"fix frontmatter\", \"skill compliance\", \"frontmatter audit\", \"score skill\", \"check skill tokens\". INVOKES: token counting tools, test runners, git commands. FOR SINGLE OPERATIONS: use token CLI directly for counts\u002Fchecks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2786,2787,2788,2791],{"name":11,"slug":8,"type":16},{"name":2637,"slug":2638,"type":16},{"name":2789,"slug":2790,"type":16},"Process Optimization","process-optimization",{"name":2741,"slug":2742,"type":16},"2026-07-12T08:17:32.970921",{"slug":2794,"name":2794,"fn":2795,"description":2796,"org":2797,"tags":2798,"stars":2683,"repoUrl":2684,"updatedAt":2804},"skill-authoring","author agent skills for agentskills.io","Write Agent Skills that comply with the agentskills.io specification. WHEN: \"create a skill\", \"new skill\", \"write a skill\", \"skill template\", \"skill structure\", \"review skill\", \"skill PR\", \"skill compliance\", \"SKILL.md format\", \"skill frontmatter\", \"skill best practices\". DO NOT USE FOR: improving existing skills (use sensei), general documentation. INVOKES: waza CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2799,2800,2803],{"name":2681,"slug":2682,"type":16},{"name":2801,"slug":2802,"type":16},"Plugin Development","plugin-development",{"name":2741,"slug":2742,"type":16},"2026-07-12T08:17:35.873862",109]