Skip to content

Add Claude Code plugin for FinOps hubs and Azure Cost Management#2043

Draft
MSBrett wants to merge 22 commits intodevfrom
features/agentskills
Draft

Add Claude Code plugin for FinOps hubs and Azure Cost Management#2043
MSBrett wants to merge 22 commits intodevfrom
features/agentskills

Conversation

@MSBrett
Copy link
Contributor

@MSBrett MSBrett commented Mar 4, 2026

Summary

Retry of #2013 after revert in #2023. Adds a Claude Code plugin with skills for FinOps hubs (KQL-based cost analysis) and Azure Cost Management (optimization, commitments, orphaned resources).

What's included

  • 2 skills: FinOps toolkit (hubs queries, deployment, FOCUS) and Azure Cost Management (Advisor, reservations, savings plans, orphaned resources)
  • 4 agents: CFO, FinOps practitioner, database query, hubs agent
  • 5 commands: cost-optimization, hubs-connect, hubs-healthCheck, mom-report, ytd-report
  • 1 output style: executive formatting
  • Version sync: Update-Version.ps1 now updates marketplace.json plugin versions

Issues from #2023 addressed

  • CLAUDE.md restored (symlink to AGENTS.md)
  • Packaging verified: Build-Toolkit claude-plugin resolves symlinks correctly (pwsh 7 Copy-Item -Recurse follows symlinks natively)
  • Plugin versioning aligned at 13.0.0
  • PR-2013-REVIEW-AUDIT.md removed

Test plan

  • Clean build: Build-Toolkit claude-plugin produces 293 files, 0 symlinks
  • Symlinks resolved to real content in release output
  • End-to-end plugin validation
  • ❎ Log not needed

msbrett and others added 21 commits February 9, 2026 11:38
…oolkit

Introduces the Claude Code plugin structure under src/ai-tools/ with:
- Agents: finops-practitioner, chief-financial-officer, ftk-database-query, ftk-hubs-agent
- Skills: azure-cost-management and finops-toolkit with reference docs and KQL query catalog
- Commands: hubs-connect, hubs-healthCheck, mom-report, ytd-report
- Output style: fact-grounded financial analysis formatting with evidence requirements
- Plugin manifest and marketplace configuration

Moves KQL queries from src/queries/ into skill reference structure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add .ftk/environments.local.md settings pattern for multi-environment config
- Rename command files from .prompt.md to .md for auto-discovery
- Replace all "project configuration" references with .ftk/environments.local.md
- Add settings-format.md reference documentation
- Update marketplace.json source to relative path
- Add docs publishing workflow to CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reorganize plugin components into the new src/claude-plugin directory
structure with updated plugin.json, README files, and marketplace config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single source of truth for agent instructions across Claude Code,
GitHub Copilot, and other AI coding tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes verified against live Azure APIs and repo source docs:
- azure-advisor: remove fabricated GUID row, add dismiss vs postpone note
- azure-credits: update stale product names (Ubuntu Pro, Citrix Virtual Apps)
- azure-savings-plans: fix REST method, API version, default params, embed scripts
- azure-reservations: new reference file for reserved instance analysis
- azure-commitment-discount-decision: new decision framework reference
- finops-hubs: add Transactions() to function list
- finops-hub-database-guide: fix CostsPlus phantom reference to costs-enriched-base
- ftk-hubs-connect: fix daterange() typo to datestring()
- quarterly-cost-by-resource-group: fix description to match top N row semantics
- Remove azure-storage-cost-analysis (non-functional)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Relocated claude-plugin from src/claude-plugin to src/templates/claude-plugin
so it gets packaged by Package-Toolkit.ps1. Moved queries back to src/queries/
with symlink into plugin. Added docs-mslearn symlink and linked all 103
Microsoft Learn docs in finops-toolkit SKILL.md. Updated marketplace.json
path, reverted copilot-instructions.md and settings.json, added changelog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nalysis

New reference files for orphaned resource detection (Resource Graph queries
for 8 resource types), Azure Retail Prices API (public pricing lookup), and
VM rightsizing workflow (Advisor + Monitor metrics + price validation). New
/ftk-cost-optimization command orchestrates all references into a structured
report. Updated SKILL.md with 3 new domains and trigger keywords. Added
cross-references from azure-advisor.md to rightsizing and orphaned resource
docs. Includes red/blue team remediation: fixed RI price calculation, VMSS
NIC exclusion, snapshot chain filtering, LB query null handling, bulk
cleanup error handling, BSD date syntax, Measure-Object scriptblock, and
Impact sort ordering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Update ms.date in changelog.md to today's date so the "Update ms.date
in docs-mslearn" workflow has nothing to push, avoiding the branch
protection failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore CLAUDE.md as a regular file (was symlink to copilot-instructions.md),
make AGENTS.md and .github/copilot-instructions.md symlink to CLAUDE.md,
and update marketplace.json paths and categories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The query catalog table and coding standards section were moved to the
skill reference layer, keeping the agent prompt focused on domain
expertise and operational behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AGENTS.md is now the canonical agent instructions file. CLAUDE.md and
.github/copilot-instructions.md are symlinks pointing to it, ensuring
all AI agents (Claude, Copilot) share the same instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remediate 19 review items from flanakin's post-merge review of the
Claude Code plugin (reverted in PR #2023). Key changes:

- Update plugin version to 13.0.0 and integrate into Update-Version.ps1
- Fix plugin.json description (FinOps is a proper noun)
- Update FinOps Framework to 2025 Fx (4 principles, 2 domain names)
- Move commands into ftk/ subfolder for /ftk:* namespacing
- Prefix all working paths with ftk/ (visible, not .ftk/)
- Replace platform detection with tool availability detection
- Add phase checkpoints to mom-report, document iterative design intent
- Strengthen what-if as required pre-deployment step
- Fix Get-VmSkuPrice array bug (Select-Object -First 1)
- Copy Get-BenefitRecommendations.ps1 from azcapman
- Add FinOps alerts capability, rename to FinOps workbooks
- Update changelog version to v14
- Add PR-2013-REVIEW-AUDIT.md tracking all 19 items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Match repo convention: "MIT License" (uppercase L) per finops-toolkit
style. Script sourced from microsoft/azcapman (MIT licensed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove azure-capacity-management plugin entry from marketplace.json
and source script links from azure-advisor.md and azure-anomaly-alerts.md.
This repo should have no cross-references to external repos.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…remove audit file

- Update SKILL.md files with streamlined task routing and best practices
- Add version sync for marketplace.json in Update-Version.ps1
- Improve command references and plugin metadata
- Remove PR-2013-REVIEW-AUDIT.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolved conflicts:
- .github/copilot-instructions.md: kept symlink to AGENTS.md
- docs-mslearn/toolkit/changelog.md: merged both changelog entries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: Review 👀 PR that is ready to be reviewed label Mar 4, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MSBrett MSBrett requested a review from Copilot March 4, 2026 16:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Claude Code plugin template to the FinOps Toolkit repo, providing FinOps hubs (KQL-based) and Azure Cost Management workflows, agents, commands, and an executive output style, plus version sync updates.

Changes:

  • Added Claude plugin template (skills, agents, commands, output style) for FinOps hubs + Azure Cost Management.
  • Added extensive reference documentation and embedded scripts (e.g., Benefit Recommendations PowerShell).
  • Updated version automation (Update-Version.ps1) to sync Claude plugin versions in plugin.json and .claude-plugin/marketplace.json.

Reviewed changes

Copilot reviewed 46 out of 48 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/templates/claude-plugin/skills/finops-toolkit/references/workflows/ftk-hubs-healthCheck.md Adds FinOps hubs health check workflow reference
src/templates/claude-plugin/skills/finops-toolkit/references/workflows/ftk-hubs-connect.md Adds FinOps hubs cluster discovery/connect workflow reference
src/templates/claude-plugin/skills/finops-toolkit/references/settings-format.md Documents .ftk/environments.local.md format used by commands
src/templates/claude-plugin/skills/finops-toolkit/references/queries Adds link/symlink to shared query catalog for the plugin
src/templates/claude-plugin/skills/finops-toolkit/references/finops-hubs.md Adds FinOps hubs analysis guidance for the plugin skill
src/templates/claude-plugin/skills/finops-toolkit/references/finops-hubs-deployment.md Adds hubs deployment guidance for the plugin skill
src/templates/claude-plugin/skills/finops-toolkit/references/docs-mslearn Adds link/symlink to Microsoft Learn content within the plugin
src/templates/claude-plugin/skills/finops-toolkit/SKILL.md Defines the finops-toolkit skill triggers/routing and references
src/templates/claude-plugin/skills/finops-toolkit/README.md Documents the finops-toolkit skill contents and usage
src/templates/claude-plugin/skills/azure-cost-management/references/azure-vm-rightsizing.md Adds VM rightsizing workflow reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-savings-plans.md Adds savings plans guidance + embedded script documentation
src/templates/claude-plugin/skills/azure-cost-management/references/azure-retail-prices.md Adds Retail Prices API lookup reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-reservations.md Adds reservations guidance and comparison patterns
src/templates/claude-plugin/skills/azure-cost-management/references/azure-orphaned-resources.md Adds ARG orphaned-resource detection and cleanup patterns
src/templates/claude-plugin/skills/azure-cost-management/references/azure-macc.md Adds MACC tracking workflow reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-credits.md Adds Azure credits/prepayment tracking reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-cost-exports.md Adds Cost Management exports configuration reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-commitment-discount-decision.md Adds commitment discount decision framework reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-budgets.md Adds budgets creation/notification reference
src/templates/claude-plugin/skills/azure-cost-management/references/azure-anomaly-alerts.md Adds anomaly alert deployment reference (PowerShell/Bicep)
src/templates/claude-plugin/skills/azure-cost-management/references/azure-advisor.md Adds Advisor querying/suppression reference
src/templates/claude-plugin/skills/azure-cost-management/references/Get-BenefitRecommendations.ps1 Adds script for Cost Management benefit recommendations
src/templates/claude-plugin/skills/azure-cost-management/SKILL.md Defines the azure-cost-management skill triggers and references
src/templates/claude-plugin/skills/azure-cost-management/README.md Documents the azure-cost-management skill contents and usage
src/templates/claude-plugin/output-styles/ftk-output-style.md Adds output style for evidence-based financial reporting
src/templates/claude-plugin/commands/ftk/ytd-report.md Adds YTD report command workflow
src/templates/claude-plugin/commands/ftk/mom-report.md Adds month-over-month report command workflow
src/templates/claude-plugin/commands/ftk/hubs-healthCheck.md Adds hubs health check command workflow
src/templates/claude-plugin/commands/ftk/hubs-connect.md Adds hubs connect command workflow
src/templates/claude-plugin/commands/ftk/cost-optimization.md Adds cost optimization command workflow
src/templates/claude-plugin/agents/ftk-hubs-agent.md Adds hubs deployment/troubleshooting agent
src/templates/claude-plugin/agents/ftk-database-query.md Adds KQL/database querying agent
src/templates/claude-plugin/agents/finops-practitioner.md Adds FinOps practitioner agent
src/templates/claude-plugin/agents/chief-financial-officer.md Adds CFO agent
src/templates/claude-plugin/README.md Documents how to install/use the Claude plugin template
src/templates/claude-plugin/.claude-plugin/plugin.json Adds Claude plugin manifest and MCP server configuration
src/templates/claude-plugin/.build.config Adds build config for plugin packaging
src/scripts/Update-Version.ps1 Updates versioning script to sync plugin and marketplace versions
src/queries/finops-hub-database-guide.md Updates query best-practice pointer to costs-enriched-base
src/queries/catalog/quarterly-cost-by-resource-group.kql Adjusts header comments to match intended query semantics
src/queries/catalog/costs-enriched-base.kql Updates schema reference comment in the base query
docs-mslearn/toolkit/changelog.md Adds changelog entry for the plugin and updates ms.date
CLAUDE.md Replaces content with a link to AGENTS.md
AGENTS.md Adds agent guidance file content (restored from CLAUDE.md)
.github/copilot-instructions.md Replaces content with a link to AGENTS.md
.claude-plugin/marketplace.json Adds marketplace listing with finops-toolkit plugin entry

Comment on lines +38 to +43
### Claude Code plugin v14

- **Added**
- Added Claude Code plugin with skills for FinOps hubs and Azure Cost Management.
- Added 4 agents (CFO, FinOps practitioner, database query, hubs agent), 4 commands, and an output style.
- Moved KQL query catalog from `src/queries/` into the plugin.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changelog entry appears internally inconsistent with the PR contents: it calls this “plugin v14” while the plugin manifest is versioned 13.0.0, it says “4 commands” but this PR adds 5 (/ftk-hubs-connect, /ftk-hubs-healthCheck, /ftk-mom-report, /ftk-ytd-report, /ftk-cost-optimization), and it states the query catalog was moved (it looks referenced/linked rather than relocated). Please align the changelog section/versioning and counts with what’s actually shipped.

Suggested change
### Claude Code plugin v14
- **Added**
- Added Claude Code plugin with skills for FinOps hubs and Azure Cost Management.
- Added 4 agents (CFO, FinOps practitioner, database query, hubs agent), 4 commands, and an output style.
- Moved KQL query catalog from `src/queries/` into the plugin.
### Claude Code plugin v13.0.0
- **Added**
- Added Claude Code plugin with skills for FinOps hubs and Azure Cost Management.
- Added 4 agents (CFO, FinOps practitioner, database query, hubs agent), 5 commands (`/ftk-hubs-connect`, `/ftk-hubs-healthCheck`, `/ftk-mom-report`, `/ftk-ytd-report`, `/ftk-cost-optimization`), and an output style.
- Linked to the existing KQL query catalog in `src/queries/` from the plugin.

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +66
let version = toscalar(database('Ingestion').HubSettings | project version);
Costs
| summarize
Cost = numberstring(sum(EffectiveCost)),
Months = dcount(startofmonth(ChargePeriodStart)),
DataLastUpdated = daterange(max(ChargePeriodStart))
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This KQL snippet is very likely invalid as written: daterange() and numberstring() are not standard Kusto functions, and Costs is inconsistent with the rest of the plugin guidance that describes function-based access (e.g., Costs()). Also, it queries database('Ingestion') to read HubSettings, which conflicts with the skill docs that say to never use the Ingestion database. Suggestion: use standard KQL formatting functions (e.g., format_datetime, format_number), invoke the Costs function/table correctly, and either retrieve hub version from the Hub database (if available) or update the skill guidance to explicitly allow this one Ingestion read for version discovery.

Suggested change
let version = toscalar(database('Ingestion').HubSettings | project version);
Costs
| summarize
Cost = numberstring(sum(EffectiveCost)),
Months = dcount(startofmonth(ChargePeriodStart)),
DataLastUpdated = daterange(max(ChargePeriodStart))
let version = toscalar(database('Hub').HubSettings | project version);
Costs()
| summarize
Cost = format_number(sum(EffectiveCost), 'N2'),
Months = dcount(startofmonth(ChargePeriodStart)),
DataLastUpdated = format_datetime(max(ChargePeriodStart), 'yyyy-MM-dd')

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,98 @@
# Connect to a FinOps hub cluster
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as the command version: numberstring() / datestring() are not standard Kusto functions, and Costs likely needs to be invoked as Costs() if it is the FinOps hubs function described elsewhere in this plugin. Recommend switching to standard KQL formatting functions and making usage consistent with the documented function-based access pattern.

Copilot uses AI. Check for mistakes.
- `clusterShortUri`
- Subscription name

If you don't find any FinOps hub instances, inform the user that you couldn't find any FinOps hubs and ask them to provide a subscription or cluster URI to connect. If they provide a subscription, repeat step 2 with that subscriptioin name or ID. If they provide a cluster URI, use that for the session and skip to step 4.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct spelling of 'subscriptioin' to 'subscription'.

Suggested change
If you don't find any FinOps hub instances, inform the user that you couldn't find any FinOps hubs and ask them to provide a subscription or cluster URI to connect. If they provide a subscription, repeat step 2 with that subscriptioin name or ID. If they provide a cluster URI, use that for the session and skip to step 4.
If you don't find any FinOps hub instances, inform the user that you couldn't find any FinOps hubs and ask them to provide a subscription or cluster URI to connect. If they provide a subscription, repeat step 2 with that subscription name or ID. If they provide a cluster URI, use that for the session and skip to step 4.

Copilot uses AI. Check for mistakes.

## Step 2: Check the latest data refresh/update date

If the last data refresh/update date less than 24 hours ago, skip this step.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar fix: this sentence is missing 'is' (for example: 'If the last data refresh/update date is less than 24 hours ago...').

Suggested change
If the last data refresh/update date less than 24 hours ago, skip this step.
If the last data refresh/update date is less than 24 hours ago, skip this step.

Copilot uses AI. Check for mistakes.
"mcpServers": {
"azure-mcp-server": {
"command": "npx",
"args": ["-y", "@azure/mcp@latest", "server", "start", "--namespace", "kusto", "--read-only"]
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using @azure/mcp@latest makes builds non-reproducible and increases supply-chain risk (a new release can change behavior or introduce breaking changes without review). Consider pinning to a specific known-good version (and updating it intentionally), while keeping the rest of the args the same.

Suggested change
"args": ["-y", "@azure/mcp@latest", "server", "start", "--namespace", "kusto", "--read-only"]
"args": ["-y", "@azure/mcp@0.2.0", "server", "start", "--namespace", "kusto", "--read-only"]

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +124
$json = Get-Content $_ -Raw | ConvertFrom-Json
$json.version = $ver
$json | ConvertTo-Json -Depth 10 | Out-File $_ -Encoding utf8 -NoNewline
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing JSON back out with Out-File -Encoding utf8 can produce inconsistent encodings across environments (especially if the script is ever run under Windows PowerShell 5.1, where UTF-8 typically includes a BOM). To avoid noisy diffs and tooling issues, consider using a BOM-less encoding consistently (e.g., utf8NoBOM) and ensure the chosen approach matches the repo’s existing file encoding conventions.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs: Review 👀 PR that is ready to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants