Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Find and quantify CI/cron and cloud-spend waste. Audit repos, run read-only provider billing checks, preview or apply CI auto-fixes, and render a monthly cost digest.
.claude/skills/hashgraph-online-costguard/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 96% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 87% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 54% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -5% | 0% |
Drive Costguard — a read-only cost auditor for CI minutes, cron schedules, and cloud provider billing (GitHub Actions, Vercel, Supabase, Railway, Netlify, Neon, Cloudflare, and more). It finds waste, estimates the monthly dollar cost, and can surgically auto-fix CI workflow files. It never writes to provider accounts, never pushes git, and never prints tokens.
Map the user's request to one Costguard CLI call and run it from the repo root.
Costguard reads a workspaces.json registry from the current working directory, so run it from a project that has one (or run registry init first). Pick the launcher that matches your context; below, costguard <subcommand> means whichever you use.
When this skill is loaded from the Costguard plugin, run the bundled build — it ships a prebuilt dist/cli/index.js, so no build step is needed. Locate the plugin root (the dir containing dist/cli/index.js):
${CLAUDE_PLUGIN_ROOT}:bash node "${CLAUDE_PLUGIN_ROOT}/dist/cli/index.js" <subcommand> ...
SKILL.md to the dir holding.codex-plugin/plugin.json:
bash node "<plugin-root>/dist/cli/index.js" <subcommand> ...
No checkout and no build — run the published CLI directly:
bashnpx -y -p @costguard/costguard-mcp costguard <subcommand> ...
Or, if costguard is on PATH (npm i -g @costguard/costguard-mcp), use it directly: costguard <subcommand> .... Heads-up: npx -y @costguard/costguard-mcp (no -p, no subcommand) starts the MCP server, whereas npx -y -p @costguard/costguard-mcp costguard <subcommand> runs the CLI.
bashcostguard audit <workspace...> # named workspaces costguard audit --all # every registered workspace costguard audit <ws> --providers all # + read-only cloud billing checks costguard audit <ws> --ci-only # static CI checks only costguard audit <ws> --crons-only # cron checks only costguard audit <ws> --site # + read-only live-site checks (site URL from registry) costguard audit <ws> --substitutions # + cross-tool cheaper-alternative suggestions costguard audit <ws> --json # JSON instead of Markdown
Prints a report: each finding has a severity, an estimated monthly USD cost, a detail, and a fix suggestion. Report stdout verbatim.
bashcostguard scan # discover CI + cron files under the registry root costguard registry list # show registered workspaces costguard registry init # create a workspaces.json in the cwd costguard report # re-render the last saved audit run
bashcostguard fix <ws> # dry-run: print a unified-diff preview, write nothing costguard fix <ws> --apply # write the surgical edits to disk (idempotent) costguard fix <ws> --pr # also emit local PR artifacts (no push)
Default is dry-run. Only deterministic ADD-rule fixers run (timeout, concurrency, paths-ignore). Costguard never pushes; --open-pr is gated and refuses without an explicit token.
bashcostguard digest # render the digest from the last run (dry-run) costguard digest --post # delivery adapter (inert unless configured)
Detect which providers a repo uses — from config files, package.json deps, and env-var names (never values, never secrets). Covers all 13 wired providers plus inngest.
bashcostguard discover [dir] # list detected providers + evidence (default dir: .) costguard discover . --json # JSON: { dir, providers, detections } costguard discover . --write # union-merge detected providers into ./workspaces.json (non-destructive)
Read-only, GET-only checks on a live URL (no browser, no form submit, no auth replay). Flags transfer weight, oversized images, missing compression, weak cache headers, and render-blocking scripts. The $/mo headline is the single site/transfer-weight line — sourced when the host bills transfer (Vercel/Netlify), or an explicit $0 performance note (Cloudflare Pages static / unknown host). Per-asset findings (oversized-image, missing-compression) put their dollar share in detail and carry estMonthlyUsd: 0 (no double-count); a $0 performance-only page never raises a high finding, so it never fails CI on cost alone.
bashcostguard site <url> # Markdown report costguard site <url> --json # JSON findings
audit --site runs the same checks for any workspace whose workspaces.json entry has a site URL. audit --substitutions adds cross-tool <provider>/cheaper-alternative suggestions (e.g. a static Vercel/Netlify Pro site → Cloudflare Pages), each with a sourced saving, migration effort, and lock-in caveat.
--providers <ids|all> adds read-only billing checks for the providers listed on each workspace in workspaces.json. Tokens are read from the environment / .env only. A provider whose token env var is absent is skipped, not failed. Supported: github, supabase, railway, netlify, neon, vercel, sentry, upstash, atlas, cloudflare, fly, render, datadog (+ inngest detection).
Costguard also ships a bundled MCP server that exposes the same engine over a host-agnostic tool surface (Claude Code, Codex, any MCP host). It wraps the same read-only engine functions — no new behavior, same posture. In Claude Code it is declared by .claude-plugin/.mcp.json and launched from the bundled build:
json{ "mcpServers": { "costguard": { "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/dist/mcp/server.js"] } } }
In the plugin, the server runs from the committed dist/mcp/server.js — no install step.
For Codex, add one of these to ~/.codex/config.toml. Use npx for a no-checkout install (pulls the published package), or the bundled build if you run Codex from the plugin:
toml# npx — no checkout [mcp_servers.costguard] command = "npx" args = ["-y", "@costguard/costguard-mcp"]
toml# bundled plugin build [mcp_servers.costguard] command = "node" args = ["<plugin-root>/dist/mcp/server.js"]
Tools:
| Tool | Posture | |---|---| | audit_workspace | read-only; returns a Findings envelope (includeSite adds site checks) | | discover_providers | read-only; env-var NAMES only, never values | | audit_site | read-only, GET-only | | plan_fix | dry-run; returns unified diffs only, writes nothing | | apply_fix | writes local CI files; REFUSES unless confirmApply:true; never pushes git | | plan_live_checks | plans a live billing read (see below); emits a snippet only with consent | | ingest_live_reading | parses a returned billing figure into a Finding |
--live) — opt-in, consent-gated--live extends the read-only posture above: it adds browser-driven reads over your already-logged-in session, performed by the playwriter MCP server under the agent's orchestration. This is a genuine posture change and is treated as one — off by default, opt-in, and consent-gated. costguard's own tools still never drive a browser and never see credentials: plan_live_checks only emits a read-only snippet (navigation + reading rendered billing figures — no clicks, typing, form submits, credential replay, cookies, localStorage, sessionStorage, or screenshots), and ingest_live_reading only parses the returned figure. The browser action is performed by playwriter, authorized by you.
API-first / browser-fallback: plan_live_checks is API-first when a provider module exists and its API token resolves from the environment (a deterministic env-NAME check, no network probe) — in that case prefer audit_workspace. Only when there is no usable API token does it fall back to a browser playbook.
Three consent gates (all required): (1) the host's MCP tool-call consent; (2) costguard's own per-run confirmation — plan_live_checks returns a consentNotice the agent MUST surface, and emits the actionable snippet only when called with confirmLive:true; (3) playwriter's own consent before it executes.
Graceful degrade: if playwriter is not connected, the agent cannot run the snippet; ingest_live_reading returns a kind:"diagnostic" Finding (excluded from cost totals) and the audit never blocks.
DELETE to provider accounts.
directional, not invoices.
node on PATH. The bare costguard command is optional when theskill runs from the plugin — use the plugin-root node launcher above.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-04 | fail→pass | 14,620 | 5,503 | -62% | 1 | 1 | 0% | 1,671 | 3,274 | +96% | 0 | 0 | — |
case-01 | fail→fail | 14,060 | 13,157 | -6% | 1 | 1 | 0% | 2,140 | 3,019 | +41% | 0 | 0 | — |
case-02 | fail→fail | 21,641 | 9,929 | -54% | 1 | 1 | 0% | 3,211 | 2,797 | -13% | 0 | 0 | — |
case-03 | fail→fail | 13,062 | 18,007 | +38% | 1 | 1 | 0% | 1,292 | 2,928 | +127% | 0 | 0 | — |
case-05 | fail→pass | 9,168 | 2,672 | -71% | 1 | 1 | 0% | 1,577 | 2,942 | +87% | 0 | 0 | — |
case-06 | fail→pass | 15,252 | 7,101 | -53% | 1 | 1 | 0% | 1,799 | 2,838 | +58% | 0 | 0 | — |
case-07 | fail→fail | 19,224 | 17,219 | -10% | 1 | 1 | 0% | 3,916 | 2,795 | -29% | 0 | 0 | — |
case-08 | fail→fail | 12,696 | 8,335 | -34% | 1 | 1 | 0% | 2,038 | 3,058 | +50% | 0 | 0 | — |
case-09 | fail→pass | 47,873 | 3,811 | -92% | 1 | 1 | 0% | 1,996 | 3,072 | +54% | 0 | 0 | — |
case-10 | fail→pass | 22,418 | 7,176 | -68% | 1 | 1 | 0% | 3,006 | 2,845 | -5% | 0 | 0 | — |
case-11 | fail→fail | 12,470 | 27,192 | +118% | 1 | 1 | 0% | 2,216 | 2,988 | +35% | 0 | 0 | — |
case-12 | fail→pass | 16,000 | 1,955 | -88% | 1 | 1 | 0% | 1,876 | 2,743 | +46% | 0 | 0 | — |
case-13 | fail→fail | 14,268 | 7,113 | -50% | 1 | 1 | 0% | 1,749 | 2,728 | +56% | 0 | 0 | — |
case-18 | fail→pass | 32,967 | 3,281 | -90% | 1 | 1 | 0% | 5,190 | 3,007 | -42% | 0 | 0 | — |
case-14 | fail→pass | 13,941 | 7,933 | -43% | 1 | 1 | 0% | 2,498 | 2,931 | +17% | 0 | 0 | — |
case-15 | fail→pass | 9,686 | 5,034 | -48% | 1 | 1 | 0% | 864 | 3,331 | +286% | 0 | 0 | — |
case-16 | fail→pass | 14,618 | 2,405 | -84% | 1 | 1 | 0% | 2,770 | 2,939 | +6% | 0 | 0 | — |
case-17 | fail→pass | 8,989 | 2,987 | -67% | 1 | 1 | 0% | 1,402 | 3,023 | +116% | 0 | 0 | — |
case-19 | pass→pass | 20,942 | 16,836 | -20% | 1 | 1 | 0% | 3,385 | 4,169 | +23% | 0 | 0 | — |
case-20 | pass→pass | 9,951 | 10,005 | +1% | 1 | 1 | 0% | 1,451 | 4,240 | +192% | 0 | 0 | — |
case-21 | pass→fail | 12,115 | 17,136 | +41% | 1 | 1 | 0% | 2,071 | 2,945 | +42% | 0 | 0 | — |
case-22 | fail→fail | 15,894 | 15,206 | -4% | 1 | 1 | 0% | 2,097 | 3,621 | +73% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 16 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.