Skip to content

Detect your own patterns

Run a check leancosts does not ship as a detector (your rule, your agent, your timing) and file what it finds as a change request that your team approves and the savings ledger measures.

Three tools do it, in one conversation with your MCP client:

StepToolWhat it does
1search_resourcesselects the estate (cloud, type, tag, cost band)
2list_resource_metricsreads the signal for up to 500 of them at once
3create_change_requestfiles the finding, with the pattern attached
  • An MCP client connected to leancosts: Connect Claude to leancosts.
  • The change_request.create capability on the token or session you connect with. Without it, step 3 is refused before it validates anything.
  • At least one sync finished, so your bill and your metric windows exist.

The Copilot page carries this prompt under Detect your own patterns, ready to copy. Edit the filter and the threshold to your own check:

Find Azure disks tagged env=prod that have been unattached for more than 30
days. Use search_resources, then list_resource_metrics for the ones you select,
then create_change_request with op delete for each and the detectionPattern
filled in. Do not estimate the saving yourself.

The last line matters, and step 3 says why.

search_resources takes the filter (providers, resourceTypes, resourceGroups, accountIds, tagKey + tagValue, tagMissingKey, minMonthlyCost / maxMonthlyCost) and returns each hit with the monthly cost your bill attributed to it.

list_resource_metrics then reads the persisted utilization windows for up to 500 resources in one call, so checking one signal across an estate costs one call rather than one per resource. Ids match case-insensitively.

freshestIngestedAt tells you how recent the newest row in the answer is. A stale stamp is the reason to distrust everything above it.

create_change_request takes the title, the why, the scope, the changes (one row per resource, op = create · update · delete), optional links, and submitImmediately. When the change acts on a finding leancosts already holds, pass its id from list_opportunities as opportunityId: the saving is then booked once, never beside your team’s own “applied” answer. Naming a finding does not change its status in the register. The finding must be in your organization and name a resource the change request covers.

Do not send an estimate. There is no field for one on a row, and the top-level estimatedMonthlyImpactUsd exists only so that passing it is refused rather than silently ignored. leancosts derives the number itself:

  • Each delete row is priced from that resource’s last closed month on your bill (the same figure search_resources showed your agent) and appends one auditable line to why: Estimate: <resourceId>: -$<amount> last closed month, measured.
  • A resource your bill never attributed a cost to comes back under unpriced and contributes nothing to the total. A missing bill line is not a measured zero.
  • update and create rows are never priced. A resize estimate would need a price-book target, and an invented one is a claim no bill can back.
  • When nothing could be priced, the estimate is empty, not $0.

detectionPattern records what you compared:

{
"filter": { "providers": ["azure"], "resourceTypes": ["microsoft.compute/virtualmachines"], "tagKey": "env", "tagValue": "prod" },
"signals": [
{ "metric": "Percentage CPU", "aggregation": "p95", "windowDays": 30, "comparator": "below", "threshold": 3 }
],
"action": "stop"
}

Use the metric names your own answer from step 2 carried; Percentage CPU is the Azure VM one.

Every signals[].metric must be a name your organization’s ingestion actually writes. Name one it does not and the call is refused, listing the metrics the resources in this change request do carry, so run step 2 first. signals: [] is fine when you detected on inventory alone (an unattached disk older than 30 days has no metric to name).

  1. The tool answers with the change request, its derived estimatedMonthlyImpactUsd and the unpriced list, plus: “Filed. The change request needs a human approval; leancosts does not apply it.”
  2. Open Savings register → Change requests. The new row carries the pill Your agent.
  3. Open it: the rationale shows one Estimate: line per priced resource, and the detection pattern block under the scope shows your filter as chips, one line per signal, and the action.
  4. Approve and execute it the way you would any other change request: Act on a cost finding. Your team runs the change with its own credentials; leancosts never touches your cloud.
  5. After the next bill lands, the Impact tab of the same hub carries the measured delta, the only number that counts as saved.
  • Not a rules engine. leancosts stores no rule, schedules no check and runs no code of yours. Your agent runs when you run it.
  • Not an approval bypass. An agent-filed change request needs the same human approval as any other, and the agent cannot approve its own.
  • Not a write path. No tool on this endpoint changes anything in your cloud.

Every tool your client can call is listed in Use leancosts with an agent.