Skip to main content
Glama
getnable

nable (finops-mcp)

by getnable

nable

nable prices what your coding agents are about to do, before they do it. Free, local, one command.

PyPI PyPI Downloads Tests License: Apache-2.0 MCP Toplist

nable puts a check in front of the commands a coding agent is about to run, in Claude Code, Cursor, Codex CLI, GitHub Copilot, Gemini CLI and Cline (and in front of MCP tool calls in the first three). A launch is priced at list price before it runs, a one-way door (destroy, terminate, a commitment purchase) stops for a human, and every verdict goes to a hash-chained ledger on your machine. The guard needs no cloud account, no API key and no license.

nable is also an open-source (Apache-2.0), local-first FinOps tool for cloud and AI cost: a read-only scan that finds waste in your AWS account using only free APIs, AI coding-agent spend priced per model with per-session caps, and AI cost split by project, team and user. It runs in your terminal or as an MCP server inside Claude, Cursor and VS Code. nable sends your billing data to no service of its own; in an editor, the answers you ask for reach the model you chat with, as every MCP tool result does.

Try it

uvx nable guard install      # Claude Code, this project. --all: every agent found. --global: every project.
uvx nable guard try          # see it first: four sample commands through the gate, nothing executed

What the agent gets back when it tries a costly launch or a destroy (real output, no cloud account needed):

$ uvx nable guard check --command "aws ec2 run-instances --instance-type p4d.24xlarge --count 8"
  ask  nable guard: 8x p4d.24xlarge at $21.9576/hr (on-demand us-east-1 list price) is ~$128,233/mo. The +$128,233/mo impact is over your $500 auto threshold; a human should review it. Budget not checked: there is no spend figure on this machine yet; `nable budget refresh` computes one.

$ uvx nable guard check --command "terraform destroy -auto-approve"
  ask  nable guard: This would destroy infrastructure (`terraform destroy -auto-approve`). It cannot be undone; confirm to proceed.

Using the Claude Code plugin? Installing it turns the guard on, no second step:

/plugin marketplace add getnable/finopsmcp
/plugin install nable@nable

nable guard off (or FINOPS_GUARD=off) pauses every nable hook and nable guard on resumes it; an agent that tries nable guard off itself is asked about first.

In Claude Code, Cursor and Copilot CLI, ask stops the agent until you confirm; Codex CLI, Gemini CLI, Cline and Copilot's cloud agent refuse the command and show the reason (per-agent table under "Guard hook" below). A launch under the threshold stays silent: a t3.micro is ~$8/mo, under the default $500/mo (FINOPS_POLICY_MAX_AUTO_USD). Restart the agent after installing so it picks up the hook.

What needs a cloud account: pricing and asking do not. The budget stop, nable guard reconcile (CloudTrail) and the scan below read your own account, read-only.

Related MCP server: cloudscope-mcp

Scan what is already running

uvx nable scan
nable scan · profile prod
account 3521… · this account only
scanning 17 regions …
  us-east-1 ......... 17 findings
  eu-west-1 ......... 1 finding
────────────────────────────────────────────
$659/mo recoverable
       $350/mo  1 idle RDS instance (db.r5.xlarge MySQL, no connections in 14 days), eu-west-1
       $210/mo  14 unattached EBS volumes (2.1 TB, gp2), us-east-1
     $98.55/mo  3 idle NAT gateways, us-east-1
run `nable scan --spend` for the spend breakdown (uses Cost Explorer, ~$0.02)

Uses the AWS credentials already on your machine and reads only free cloud APIs, so scanning never adds to your bill. uvx nable scan --demo runs on sample data with no account at all. Add --json for CI, or --spend for a deeper breakdown.

uvx nable commitments status lists the RDS, EC2, ElastiCache, Redshift, OpenSearch and MemoryDB reservations and the Savings Plans the account holds and when each ends, from free reads; --fail-within 30 makes it a CI check (exit 1 when one ends within 30 days, 2 when one could not be read). examples/github-actions/commitments-status.yml runs it every week through a read-only role assumed with GitHub OIDC and keeps the JSON.

From there nable:

  • Shows what you spend across AWS, Azure, GCP, Kubernetes, and 15 AI, data and SaaS providers, in one place.

  • Finds what you are wasting (idle servers, oversized databases, forgotten storage) and puts a dollar figure on each one.

  • Fixes it, with your approval, by opening a pull request, then confirms the change happened and measures the saving: from your bill when CUR line items cover it, otherwise at your effective or list rate, labeled as an estimate.

  • Budgets your AI agents: nable ai-budget prices Claude Code and Codex CLI usage per model from local logs, with a per-session cap; nable ai-costs --by project|team|user splits OpenAI, Anthropic, LiteLLM and Langfuse spend.

nable demo: a sample bill in seconds

Use it in your editor

uvx nable runs as a local MCP server inside Claude, Cursor, and VS Code, on your existing Claude or Cursor membership, no API key and no per-token cost. Then ask:

  • "Why did our AWS bill jump last month?"

  • "How much are we spending on OpenAI and Anthropic?"

  • "Which instances should we downsize?"

  • "Open a Jira ticket for any waste over $200/mo"

How nable compares

nable

AWS Cost Explorer

Vantage / CloudHealth

Infracost

Open source

Yes (Apache-2.0)

No (AWS's Billing MCP server is)

No

The CLI (Apache-2.0); Infracost Cloud is SaaS

Where your data lives

Your machine

AWS

Vendor SaaS

Your machine or CI; resources are priced through Infracost's hosted pricing API

Clouds covered

AWS, Azure, GCP, Kubernetes

AWS only

Multi-cloud

IaC, any cloud

AI and GPU spend

Yes (OpenAI, Anthropic, Bedrock, Vertex AI, GPUs)

AWS services only (Bedrock, SageMaker, GPU instances)

Vantage: yes; CloudHealth: an AI and token dashboard

No

Runs in Claude / Cursor / VS Code

Yes (local MCP)

AWS's Billing and Cost Management MCP server

Vantage: hosted MCP server; CloudHealth: none found

Agent plugins for Claude Code, Cursor and others; IDE extensions

Prices an agent's command before it runs

Yes: a hook in Claude Code, Cursor, Codex CLI, Copilot, Gemini CLI and Cline prices launches, stops one-way doors, and logs every verdict

No

No

Not as a hook on commands; its agent skills price IaC as it is written, and CI prices the pull request

Fixes waste

Opens a pull request, you approve

No

Vantage: a FinOps agent that remediates with approval; no IaC pull request found

AutoFix PRs for policy issues in IaC code, not from what running resources use

Answers

What an agent is about to spend; what you spend and waste now

AWS spend

Multi-cloud spend

Cost of an IaC change before deploy

Price

Free (local); paid plans are flat, never a percentage of spend

Console free; API $0.01 per request

Vantage: free up to $2,500/mo of tracked spend, then paid; CloudHealth: paid

CLI free; Infracost Cloud paid

Infracost prices an infrastructure change as it is written and in the pull request; nable's guard prices the command an agent is about to run, wherever it came from, and the scan finds waste in what is already running. Other products' rows were checked on 2026-10-13; the sources are listed in CAPABILITIES.md. Fuller breakdowns: nable vs Vantage, vs CloudHealth, vs Kubecost.

Agent guard

nable guard install adds a hook to Claude Code (and --all to every supported agent it finds: Cursor, Codex CLI, GitHub Copilot, Gemini CLI, Cline) that checks each infrastructure command, or MCP call in Claude Code, Cursor and Codex, before it runs: a one-way door (destroy, terminate, a commitment purchase) asks you first, and a launch is priced at list price so a ~$128k/mo run-instances (8x p4d.24xlarge) asks instead of passing. An EC2 Capacity Reservation is priced the same way, since it bills from creation whether or not anything runs in it; with a commitment duration it is a commitment purchase, and asks whatever the policy says. The purchases it covers, and the ones it does not, are listed in CHANGELOG.md. It also watches the pattern across calls: a velocity cap on the monthly run-rate let through per hour (FINOPS_POLICY_VELOCITY_CAP_USD, default four times the $500/mo per-action threshold) and loop detection for the same creation repeated (three identical create-stack in ten minutes asks). Every verdict goes to a local hash-chained ledger.

AI budgets that stay current. When a Claude Code, Codex or Cursor spend cap is set, the guard weighs each call against it. Cursor usage comes from its Admin API (CURSOR_ADMIN_API_KEY): the hook never waits on the network, and when its copy is over an hour old it refreshes it in the background and says so (FINOPS_GUARD_BACKGROUND_REFRESH=0 turns that off). FINOPS_GUARD_AUTO_REFRESH_BUDGET=1 does the same for the cloud-budget figure, recomputing it from local cost history with no billed calls.

Team and per-developer AI budgets, as plain files. An ai_budget fact in your org model's budgets.yaml sets a monthly budget for a team (monthly_usd, and per_person_usd for each of its people), for one person (an email or github:login) or for the org, in list-price-equivalent US dollars: what the agents' tokens cost at the provider's published rate (llm_prices), usage and not an invoice. At the agent's next shell or MCP call, the guard compares this machine's month-to-date coding-agent spend with the person's budget, else their team's per_person_usd (a proposed personal budget only adds an ask, it never takes a confirmed per-person budget away), and with the team's and the org's monthly_usd (this machine alone, so a team's figure can only be under-counted, and the ask says so). Over one, it asks, naming the file, the fact key, the figure and its price source; FINOPS_GUARD_STOP_ON_BUDGET=1 or on_budget_breach: deny makes it a deny. A proposed budget, or one from a repo you have not trusted, only asks. The stricter of this and nable ai-budget's own caps answers. Whose budget it is: FINOPS_GUARD_PERSON, else git's user.email (read once and kept). The guard asks before an agent changes git's user.email, whether with git config (an include.path or includeIf that can set it included) or by writing a git config file directly: the repo's .git/config, ~/.gitconfig and the XDG one are among the guard's own files. Should the email change some other way, the next call asks once, naming both, and the earlier one's budgets still apply for the rest of the month. Tokens of a model llm_prices has no cited rate for are counted and said, never priced at a guess. The month is priced once and kept (0600, beside ai-budget.json), so a call over unchanged transcripts prices nothing and a growing one prices only its new lines.

A team's whole figure, from a paid workspace. On a paid workspace, nable cloud status --box https://HOST also reads the box's month to date for you, your teams and the org, and keeps it in cloud-standing.json beside the ledger. The guard then compares, for each budget, the larger of this machine's figure and the box's, never their sum, and says both, the box's as-of time and its age. It reads the file only, never the network, and only for this UTC month, this person and the box and workspace this machine sends to (on a box many workspaces share, another workspace's key reads a standing that is shown and never kept for the guard). Your local budgets.yaml alone sets the thresholds. nable guard doctor says when the box's figure is not used, and why.

nable org set ai_budget --subject team:payments --monthly-usd 5000 --per-person-usd 400
nable org set ai_budget --subject person:alice@acme.com --monthly-usd 300

Stops tied to the budget. A priced change is also checked against the cloud budgets you set (the set_budget tool or a budget.yml): when month-to-date spend plus the change's cost for the rest of the month would take a budget over its limit, the guard asks, naming the budget, the spend so far, the change's monthly figure and the projected overage. on_budget_breach: deny in nable.policy.yaml (in nable's data directory, ~/.finops by default, or at FINOPS_POLICY_FILE) makes that a hard stop; FINOPS_GUARD_STOP_ON_BUDGET=1 or =0 overrides it for one session or CI run. Total, provider and service budgets apply from the command itself; team and account budgets apply when FINOPS_GUARD_TEAM or FINOPS_GUARD_ACCOUNT names them where the agent runs. The hook reads a small spend summary rather than the database: every budget check writes it, nable budget refresh is the one to schedule, and a figure older than 48 hours (FINOPS_GUARD_BUDGET_MAX_AGE_HOURS) or from last month is not used, which the verdict on a priced change says. nable guard doctor lists the budgets the guard enforces, the ones it cannot place a change in, and the age of its figure.

nable guard report --session <id>     # what it asked, blocked and let through, in dollars
nable guard reconcile --hours 24      # CloudTrail's creates, destroys and commitments against the ledger
nable guard export --format cef       # the verified ledger, for a SIEM
nable budget refresh                  # recompute budgets and the guard's spend figure
nable budget ci-gate --fail-on-breach --json   # a pipeline step that fails on a breached budget

ci-gate reports and exits 0 unless --fail-on-breach is passed; with it, a breached budget (spend at or past its critical percentage) exits 1 and a check that cannot run exits 2. --budget-file budget.yml syncs the file first.

reconcile needs cloudtrail:LookupEvents (free, read-only) and matches by kind and time, since the ledger holds no resource ids. The guard is a seatbelt, not a security boundary: nable guard doctor lists what it does not see.

Purchase authority, written down. nable org set authority --class rds_ri --rung approve_each --approver email:ana@acme.com --expires 2027-06-30 writes an entry to your org model's authority.yaml: per purchase kind a paid workspace's reservation agent buys (rds_ri, elasticache_ri, database_savings_plan), its rung (off, recommend or approve_each), the most one plan may commit to it, who may approve it and when the entry expires (within 366 days). Every entry counts and the strictest answers; an entry nable cannot read holds its kind at recommend and is shown with its file, entry and field (nable org authority, nable org status). A workspace applies the stricter of the file and its own opt-in, so the file only narrows, and a named, signed-in person with the purchase grant still approves every purchase.

It guards its own settings. An agent that writes, moves or deletes the files that decide what the guard does (the org model, authority.yaml among them, nable.policy.yaml, installed packs, the ledger, the off switch, the hook entries in each agent's settings) is asked about first, from the shell in every agent and through Claude Code's Write and Edit tools too. So are nable guard off, nable org confirm and nable pack install run by an agent, from any entry point (nable, finops, finops-mcp, uvx, python -m).

Molded to your org

nable org init reads what your org already says about itself (CODEOWNERS, Terraform, AWS Organizations, tags, account and namespace names) and proposes who owns what, which environments are which, and which tag keys mean team or cost center. It then asks at most ten questions, highest spend first, most of them in bulk ("payments owns these 8 things, $18,500/mo: yes, no or edit"). Answers are stored as plain YAML in a nable.org/ folder you own: in your repo if you want it reviewed by pull request (nable org init --here), otherwise in nable's data directory.

nable org init            # propose, then ask the week-one questions
nable org status          # what is confirmed, proposed, stale or in conflict, and spend coverage
nable org questions       # the open questions, with the command that answers each
nable org export --format json

What a person confirms changes what nable does: guard asks name the owner ("Owned by payments (#payments-oncall)"), the guard takes the team for team budgets and per-team thresholds from the repo you work in, tickets carry the owner's team and channel, findings carry an owner, and attribution and prod or non-prod detection use your confirmed facts before any guess. Agents, adapters and the MCP tools can only propose; confirming takes a person at the CLI or a merged pull request. A guess may make nable more careful, never less. A nable.org/ that arrives inside a cloned repo is read on top of your own model, and until you nable org trust it, its owners are shown as likely and its thresholds may only lower yours.

It stops asking the same thing twice

The guard records how each ask was answered (Claude Code, Cursor and Copilot report when an asked command ran). When people keep approving the same kind of change in the same scope, at least 5 times over a week with nothing declined or reverted, nable proposes a threshold for that scope and shows the evidence: "approved 6 times since Sep 19, max $1,121/mo, none declined or reverted". A person confirms it with nable org confirm, and from then on that change goes through without a prompt. Repeated declines propose asking sooner. One-way doors always ask.

nable learn infer --dry-run    # what nable would propose, and why
nable guard report             # asks approved, declined and unknown, per action and scope
nable org set freeze --scope environment:prod --start 2026-11-26T00:00-05:00 --end 2026-12-01T00:00-05:00 --reason "Black Friday"
nable guard approve <id>       # let one blocked command through, once, from your own terminal

Change freezes and approval chains are org facts too: during a freeze every priced change and one-way door in its scope asks (or is denied, if you confirmed the freeze in deny mode), and remediation pull requests and tickets go to the approvers you named. Agents that cannot pause to ask (Codex CLI, Gemini CLI, Cline, the Copilot cloud agent) get a deny with an approval id; a person runs nable guard approve <id> and the identical command runs once within 15 minutes.

Packs

Packs extend nable with an org's own rules: policies, guard rules that can only tighten, remediation playbooks, price books, report templates, coding-agent skills, and (sandboxed) connectors, org adapters and ticket or Slack sinks. Each declares what it may read, which secrets it gets and which hosts it may reach in nable-pack.toml; you see that at install, and an update that asks for more waits for your approval again.

nable pack install ./my-pack          # a folder, a .tar.gz, git+https://...@<commit>, or ns/name from a registry
nable pack audit                      # what is installed, what each may do, and whether any file changed
nable pack validate ./my-pack         # for authors

An ns/name install reads a registry index named by packs.registry in your org policy, --registry or NABLE_PACK_REGISTRY; the default index (getnable/registry on GitHub) is not published yet and answers 404, so name one of your own. Your org policy file can limit where packs come from, cap what they may ask for, and require signatures (packs: in nable.policy.yaml). Details, the capability list and the honest limits of sandboxing on a laptop are in docs/PACKS.md.

Bring it into a paid workspace

Everything above runs on your machine and stays there. When you move to a paid workspace, nable cloud connect carries three things into it: your org model (the files in your org dir, budgets.yaml among them), the guard's decision ledger, each line exactly as stored, and this machine's coding-agent usage as one agent_usage record per UTC day, developer, agent, model and project for the closed days of the last 28, fewer when Claude Code keeps its transcripts for less (tokens by direction, and list-price-equivalent USD only for tokens priced at a cited llm_prices row; the project is the repo only when your org model names it, else unmapped; no prompt, file content, path or host name). The developer is whoever sends it: --as WHO, else at your terminal git's user.email, then $USER; the dry run shows it, and the workspace rolls the records up by developer, team and project. The ledger's records are your agents' commands and the paths the guard judged, with credentials redacted and nothing else changed, so they can name paths, hosts and user names; the dry run counts the records that do. It is a dry run first, and a dry run sends nothing: it prints where the bytes would go, which files and how many records, the size, the sha256 and a confirm code, and saves those exact bytes for you to read.

nable cloud connect --box https://your-workspace.example.com                        # the dry run
nable cloud connect --box https://your-workspace.example.com --send --confirm <code>
nable cloud status  --box https://your-workspace.example.com                        # what the workspace holds
nable cloud connect --box https://your-workspace.example.com --delete-org-file teams.yaml   # remove one file there
nable cloud connect --box https://your-workspace.example.com --without-org-file authority.yaml  # leave one file out

The workspace keeps each org model file you send until another upload carries that file: an upload with only owners.yaml leaves its teams.yaml as it was. A file equal to one it held and later replaced is not applied, and the send says so; --delete-org-file NAME removes a file there, and a copy of it sent after the delete applies, which is how a team goes back on purpose. authority.yaml goes only to a workspace whose box says it takes it; to any other the send is refused before anything leaves, and --without-org-file authority.yaml sends the rest without it. nable cloud status also reads your month to date and your teams' from the box, for the guard (above), when the box offers it.

--send sends exactly the bytes the confirm code names, to the box it names (the code is the sha256 of the box, a newline and the bytes), and refuses if anything changed since you looked. Run it at your own terminal, or pass --as WHO; the guard asks before an agent runs it. HTTPS only, and never in air-gap mode. The workspace key is an analyst key made on the workspace's /workspace page, read from NABLE_WORKSPACE_KEY, a --key-file with mode 0600, or a hidden prompt; it is never taken from the command line and never stored. A ledger whose hash chain breaks, and a repo's nable.org/ you have not trusted, are shown and not sent.

Setup

Requires Python 3.11+. Need uv? curl -LsSf https://astral.sh/uv/install.sh | sh (or brew install uv).

uvx nable

The setup wizard finds AWS or GCP credentials already on your machine (an SSO login, a CLI profile, or default credentials), connects the one you pick, and configures your editor. Usually you never type a key.

In CI, cron, scripts or an agent with no terminal: docs/HEADLESS.md has each command's behaviour with stdin closed, its --json output and exit codes, every environment variable, air-gap mode, and MCP over stdio.

Cursor one-click: Add nable to Cursor

Free forever for the local tool. A hosted version for teams (dashboards without a terminal, SSO, scheduled reports, always-on agents) is at getnable.com/pricing.

If finops setup doesn't auto-configure, run:

finops setup claude

Or add manually to claude_desktop_config.json:

With uvx (recommended):

{
  "mcpServers": {
    "nable": { "command": "uvx", "args": ["--python", "3.12", "finops-mcp"] }
  }
}

With absolute path:

{
  "mcpServers": {
    "nable": { "command": "/usr/local/bin/finops-mcp" }
  }
}

Use the path from which finops-mcp.

Config file locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

Why uvx? Claude Desktop is a GUI app and doesn't inherit your shell's PATH. uvx runs finops-mcp in its own isolated environment. It's the most reliable option on corporate machines with managed Python installs.

nable is not just tools your agent reads from. It is a pre-action gate your agent calls before it makes a cost-affecting change: it prices the change, checks it against your budget, and offers a cheaper path. It never applies anything itself. Propose-only, your agent proposes and a human approves.

Add one line to your agent's system prompt (Claude Code, Cursor, or any MCP client):

Before you apply any infrastructure change (a terraform apply, a helm upgrade, creating or resizing a resource) or start an expensive job, first call check_action_policy with the action and the change (a terraform plan, a helm diff, or a monthly_delta_usd). Relay the verdict, the dollar impact, and the cheaper path when one is offered. Never apply a block or an escalate action; surface it to the human. nable is advisory and propose-only.

The gate returns allow / warn / block / escalate against your policy, the monthly and annual dollar impact, and a spot alternative when the change is compute. One-way doors (delete, terminate, buy a commitment) and over-budget changes always escalate to a human, and over-budget changes are blocked outright when the policy sets on_budget_breach: deny.

And a budget for the agent itself. Run nable ai-budget once, it asks whether you are on a flat plan or a metered API and what you pay, then remembers. On a flat plan it tracks how much subsidized compute you pull for your fixed fee and warns before you run low; on metered it gates on a dollar spend cap. check_ai_budget does the same for the agent mid-task. It reads your Claude Code usage locally, nothing uploaded. Every response is priced at its own model's list rate, cache writes and reads included, and the report splits cost by model and by session. A per-task cap (nable ai-budget --session-cap 40, or "this task may spend at most $40" to the agent) is measured against one Claude Code session, subagents included, and check_ai_budget returns the headroom left under it. Add to your system prompt:

Before starting a large task, call check_ai_budget. If it returns warn or over, tell me where I stand before continuing.

It reports your real usage and burn rate against your budget, not a fabricated percentage of a plan's hidden rate limit.

nable guard install puts the same check in front of the agent's shell commands as a hook, so it runs whether or not the agent remembers to call the gate:

nable guard install --all --global      # every supported agent found on this machine
nable guard install --harness gemini    # one agent, this project only
nable guard doctor                      # what is covered here, and what is not

Agent

Where the hook goes

What it sees

When the policy wants a human

Claude Code

.claude/settings.json

shell commands, MCP tools

asks

Cursor

.cursor/hooks.json

shell commands, MCP tools

asks

Codex CLI

.codex/hooks.json

shell commands, MCP tools

denies, with the reason

GitHub Copilot

.github/hooks/nable-guard.json

shell commands

asks in Copilot CLI; denies, with the reason, in the cloud agent

Gemini CLI

.gemini/settings.json

shell commands

denies, with the reason

Cline (macOS, Linux)

.clinerules/hooks/PreToolUse

shell commands

stops the task, with the reason

--global writes the user-level file instead (~/.claude/settings.json, ~/.cursor/hooks.json, $CODEX_HOME/hooks.json, ~/.copilot/hooks/, ~/.gemini/settings.json, ~/Documents/Cline/Hooks/). A hook the user installed is one the user can remove.

Managed deployment. To make the hook a policy a user cannot remove, deploy it through the agent's admin settings. Replace <version> with the release you tested (nable --version), and make sure uvx is on the users' PATH, or use the absolute path of an installed finops binary instead of the uvx form.

Claude Code reads managed-settings.json from /Library/Application Support/ClaudeCode/ (macOS), /etc/claude-code/ (Linux and WSL) or C:\Program Files\ClaudeCode\ (Windows), or a drop-in file in managed-settings.d/ next to it. User, project and local settings add their hooks beside a managed one but cannot remove it, and a user's disableAllHooks cannot turn it off:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^(Bash|mcp__.*)$",
        "hooks": [
          {"type": "command", "command": "uvx --from finops-mcp==<version> finops guard hook", "timeout": 30}
        ]
      }
    ]
  }
}

Codex reads /etc/codex/requirements.toml (%ProgramData%\OpenAI\Codex\requirements.toml on Windows). A hook there is managed: always on, trusted without the "Hooks need review" step, and not something a user can disable:

[[hooks.PreToolUse]]
matcher = "^(Bash|mcp__.*)$"

[[hooks.PreToolUse.hooks]]
type = "command"
command = "uvx --from finops-mcp==<version> finops guard hook"
timeout = 30

Both also have a switch that runs only the managed hooks and ignores every user, project and plugin hook: "allowManagedHooksOnly": true in Claude Code's managed settings, allow_managed_hooks_only = true at the top level of Codex's requirements.toml. Set it only if no one's own hooks should run. Copilot CLI has the same idea in policy hook files, /etc/github-copilot/policy.d/*.json (root-owned, not group or world writable), in the format of .github/hooks/nable-guard.json.

Sources: Claude Code managed settings, allowManagedHooksOnly, Codex codex-rs/config/src/config_requirements.rs and codex-rs/hooks/src/engine/discovery.rs in openai/codex, Copilot hooks reference.

The guard is a seatbelt, not a security boundary: give agents read-only cloud credentials and keep write access behind a human.

Provider

What it pulls

AWS

Cost Explorer (the API bills $0.01 per request; nable scan uses only free APIs unless you pass --spend) · CUR line items through Athena (billed per byte scanned) · Organizations

Azure

Cost Management API · Advisor cost recs · VM rightsizing (Azure Monitor) · native budgets · forecast

GCP

Cloud Billing API + BigQuery billing export · Recommender

Kubernetes

a list-price estimate from your kubeconfig

OpenCost

its Allocation API, when you run OpenCost in the cluster

OpenAI

API usage and token spend by model

Anthropic

Claude API usage and token spend

Amazon Bedrock

spend by model, through Cost Explorer

Vertex AI

spend from the BigQuery billing export

OpenRouter

gateway usage

LiteLLM

spend logged by a self-hosted proxy

Langfuse

Daily metrics API: model cost, token usage, trace volume

Datadog

Usage Metering API v2: real dollar amounts

Snowflake

ACCOUNT_USAGE.METERING_HISTORY

Databricks

DBU usage and SQL warehouse spend

MongoDB Atlas

Invoice API

Twilio

Usage Records API

Cloudflare

Billing API

Vercel

Invoice API (Enterprise)

New Relic

Data ingest + user counts

Also connected, without a spend figure: Modal, Together and Replicate (nable checks the key, but their public APIs return no per-period cost, so it points you at invoice import), and Cohere and Mistral (nable cohere and nable mistral store the key; nothing reads their usage yet). Stripe, when STRIPE_SECRET_KEY is set, feeds MRR and paying customers into unit economics; it is not a cost source.

Azure roles. The Azure tools span three RBAC roles, granted to the service principal on each subscription (run finops doctor to check):

# repeat per subscription
az role assignment create --assignee <client-id> --role 'Cost Management Reader' --scope /subscriptions/<sub-id>
az role assignment create --assignee <client-id> --role Reader --scope /subscriptions/<sub-id>
az role assignment create --assignee <client-id> --role 'Monitoring Reader' --scope /subscriptions/<sub-id>

What is a FinOps MCP server? An MCP (Model Context Protocol) server that answers cloud-cost questions from inside an AI editor. nable runs locally as one, so you can ask Claude, Cursor, or VS Code about your AWS, Azure, GCP, and AI spend and it reads your real cost data on your machine to answer.

Is nable free? Yes. The terminal scan, every cost query, anomaly detection, all waste and rightsizing findings, and every connector are free forever. Every install starts with a 7-day trial of Pro features. Pro ($25/mo) adds ticket creation (Jira, Linear, GitHub Issues), email reports and digests sent on request, and the org-wide rollup across accounts. Team ($1,000/mo flat, unlimited seats) adds the conversational Slack bot and chat remediation. Forecasts, commitment recommendations, remediation PRs, and the Ledger are free today while their pricing is decided. Reports and alerts on a schedule, sent without anyone asking, are nable Cloud; this install sends them when you ask.

Does my billing data leave my machine? nable never uploads it: it reads your cost data on your machine and sends it to no nable service, and telemetry is off unless you turn it on (and never carries cost figures). The one thing that sends your own files anywhere is nable cloud connect --send, which you run to carry your org model and guard ledger into a paid workspace, and only with the confirm code its dry run showed you for those bytes and that box. In an editor, the answers you ask for reach the model you chat with, as every MCP tool result does; nable scan and the rest of the CLI involve no model. You can confirm the no-egress behavior in the source.

What clouds and providers does it support? AWS, Azure and GCP; Kubernetes (a kubeconfig estimate, or OpenCost); AI and LLM providers (OpenAI, Anthropic, Bedrock, Vertex AI, OpenRouter, LiteLLM, Langfuse); data platforms (Databricks, Snowflake, MongoDB Atlas); and SaaS (Datadog, New Relic, Cloudflare, Twilio, Vercel). Modal, Together, Replicate, Cohere and Mistral connect but return no spend figure yet (see Connectors).

How is it different from AWS Cost Explorer? Cost Explorer is AWS-only, and its API bills per request. nable is cross-cloud, runs in your terminal and in Claude/Cursor, covers AI provider spend (OpenAI, Anthropic and others) no cloud console shows, and proposes fixes as pull requests. nable scan also makes zero paid API calls by default.

Is there an open-source alternative to Vantage or CloudHealth? nable is an open-source (Apache-2.0), local-first alternative for cost queries, waste detection, rightsizing, and AI/GPU cost, running on your machine instead of a hosted SaaS.

finops-doctor          # checks credentials, DB, network, audit log
finops setup claude    # re-run editor configuration only

Symptom

Fix

Tools don't appear in Claude

Switch to uvx config or use absolute path

command not found: finops-mcp

Re-install with pip install finops-mcp or use uvx

AWS returns no data

Run finops setup aws

No matching distribution found for finops-mcp

Your Python is older than 3.11. Install on 3.11+ (uvx --python 3.12 nable, or python3.11 -m pip install finops-mcp).

cryptography build error / maturin failed

uv tried to compile on Python 3.10. Use 3.11+: uvx --python 3.12 nable.

Corporate SSL errors

pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org finops-mcp

Works at home, not at work

Use uvx (corporate IT often strips custom PATH entries)

License

Apache-2.0 in full. The hosted enterprise layer (web dashboard, scheduler, two-way Slack bot, SSO, control plane) lives in a separate private repo. What is in this one: CAPABILITIES.md; every MCP tool: docs/tool-inventory.txt.

getnable.com · Docs · Privacy · Security

mcp-name: io.github.getnable/finops-mcp

Available Tools

10 tools
check_action_policyCheck action policyA

Advisory policy gate: should a proposed remediation action proceed? Changes nothing. It is not marked read-only only because tf_dir runs terraform plan there, which executes that directory's provider plugins.

The request-path guardrail, advisory. Describe a remediation action you are considering (action_type), optionally with the change to cost (a Terraform plan, a helm diff, or a known monthly delta), and nable returns a machine verdict against your human-authored policy:

  • allow: reversible, allowlisted, and within budget. A human can apply it.

  • escalate: a one-way door (delete, terminate, buy a commitment) or an over-budget / large-cost change. A human must review it first.

  • block: the action type is not in your allowlist.

ADVICE ONLY. nable never applies the action, a human does. This is the propose-only guardrail; nable does not auto-execute anything.

action_type examples: rightsizing, tag_fix, stop_idle, spot_migration, ticket (reversible); idle_cleanup, purchase_commitment, terminate_instance, delete_resource (one-way). Policy knobs via env: FINOPS_POLICY_MAX_AUTO_USD, FINOPS_POLICY_ALLOWED_ACTIONS (comma-separated). Read-only.

Good triggers: "can the agent do X", "is this action within policy", "should I apply this fix", "is it safe to auto-apply this". Examples: - "Is this apply within policy?" - "Check this change against our cost guardrails"

NameRequiredDescriptionDefault
tf_dirNo
helm_diffNo
action_typeYes
budget_nameNo
monthly_delta_usdNo
terraform_plan_fileNo
terraform_plan_jsonNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Explicitly reconciles the readOnlyHint=false annotation ('It is not marked read-only only because tf_dir runs terraform plan there, which executes that directory's provider plugins'), which is exactly the context an agent needs. It also documents the three verdicts (allow/escalate/block), their semantics, the env knobs, and that it never executes anything.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core verdict and uses scannable bullets for allow/escalate/block, but repeats the advisory/propose-only message several times ('ADVICE ONLY', 'propose-only guardrail', 'nable does not auto-execute'), which is mild redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully defines the return verdicts and their meanings, and it explains the annotation quirk. It falls short on clarifying the four non-cost parameters, which an agent would need before calling with anything beyond the required action_type.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description must compensate. It explains action_type with concrete value examples and groups tf_dir/helm_diff/monthly_delta_usd as the three cost-related inputs, but leaves budget_name, terraform_plan_file, and terraform_plan_json entirely unexplained and doesn't map each cost option to its specific parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Advisory policy gate: should a proposed remediation action proceed?') and immediately frames the scope as propose-only. An agent can distinguish this from estimate_change_cost or get_cost_summary because it's framed as a policy verdict, not a cost estimate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit triggers ('can the agent do X', 'is this action within policy', 'should I apply this fix') plus examples, which strongly signals when to call it. It does not name sibling tools or state when NOT to use it, keeping it below a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_ai_budgetCheck AI budgetA
Read-onlyIdempotent

Advisory gate: before a big task, is the agent about to blow its AI budget?

Call this before an expensive run. Returns a verdict (ok / warn / over), the reason, a recommendation, and headroom: dollars left under this session's cap, and dollars or tokens left under the monthly budget. Advice only, it never blocks; relay the verdict and let the human decide. Pass estimated_next_tokens to test whether the next task would tip a token budget over. session_id defaults to the calling session.

NameRequiredDescriptionDefault
session_idNo
estimated_next_tokensNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent/non-destructive; the description goes further by declaring 'Advice only, it never blocks' — a critical behavioral trait no annotation conveys — and by pre-describing the return payload (verdict, reason, recommendation, headroom). It also discloses that session_id resolves to the calling session, removing a silent-default surprise.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose, then progressively more detail; each sentence carries distinct information (timing, return shape, non-blocking nature, param usage). The opening rhetorical question is slightly padded but functions as a memorable framing line.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description enumerates the return fields (verdict states, reason, recommendation, headroom) and explains the cap semantics, so an agent knows what comes back without probing. Only two optional params and both are addressed, making this complete for its complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the parameter load, and it largely does: estimated_next_tokens is given a concrete purpose and session_id is explained as defaulting to the calling session. What's missing is any guidance on magnitude/units for estimated_next_tokens or when to override session_id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb plus resource ('check ... AI budget') in the first line and pins the scope to this session's cap and the monthly budget. That scope distinguishes it from cost-oriented siblings such as get_cost_summary and estimate_change_cost, which concern cloud spend rather than agent token budget.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit invocation timing: 'Call this before an expensive run,' plus a conditional use for estimated_next_tokens ('to test whether the next task would tip a token budget over'). It also sets expectations on what to do with the result ('relay the verdict and let the human decide'), but never names a sibling or says when not to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connect_awsConnect AWSA

Connect an AWS account from inside your MCP client, no terminal needed.

Propose-then-confirm and local-only. It reads AWS credentials that already exist on this machine (named profiles, environment, the default chain), verifies each against STS, and connects the one you choose. It never creates, modifies, or deletes anything in your AWS account, and credentials stay on this machine.

Call it with no arguments first to see which accounts are available (nothing is stored). Then call it again with account_id set to the one to connect.

Examples: - "Connect my AWS account" - "Use the credentials on this machine to connect AWS"

NameRequiredDescriptionDefault
account_idNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real context beyond annotations: propose-then-confirm, credentials never leave the machine, STS verification, and a no-arg discovery pass that stores nothing. It explicitly reassures 'never creates, modifies, or deletes anything in your AWS account', which is consistent with destructiveHint=false while readOnlyHint=false correctly reflects that a connection is persisted. It doesn't say what 'connected' unlocks or whether re-connecting replaces an existing connection.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then constraints, then examples. The example utterances are mildly redundant given the prose above them, but every paragraph still carries information an agent would otherwise lack.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-optional-parameter connection tool with no output schema, the description covers the call sequence, side effects, safety profile, and credential handling — enough for an agent to invoke it correctly on the first try.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% (account_id has no description), so the description must carry the meaning — and it does: omit account_id to list available accounts, set it to the chosen identifier to connect. It doesn't state the identifier's format (account number vs profile name), which is the remaining gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Connect an AWS account') and immediately scopes it: reads existing local credentials, verifies them against STS, connects the chosen one. This clearly separates it from connect_azure and connect_gcp, which are the only plausibly confusable siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit two-call workflow: no arguments first to enumerate accounts (nothing stored), then a second call with account_id. That is exactly the sequencing an agent needs. It stops short of naming alternatives or exclusions (e.g. when to prefer connect_gcp or list_connected_providers instead), so not a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connect_azureConnect AzureA

Guide connecting Azure while keeping the service-principal secret off the model.

Azure has no local credentials nable can safely auto-detect, so connecting needs a client secret. Unlike connect_aws and connect_gcp (which read credentials already on the machine, so nothing sensitive passes through this conversation), an Azure secret would have to be pasted into the chat to reach a tool argument, which routes it through the model provider. nable does not do that. This tool returns the Cloud Shell script and has you finish the connect in your OWN terminal with finops setup azure, which encrypts the secret into your local vault. The model never sees the secret.

Examples: - "Connect Azure" - "How do I connect my Azure subscription?"

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description is rich about security behavior and the expected user flow, but it presents the tool as returning a script for the user to run later, which implies a read-only informational operation. The annotations declare readOnlyHint=false, meaning the tool is not read-only, so the description contradicts the structured behavioral hint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the key constraint (keeping the secret off the model) and then explains the why and the flow. It is somewhat verbose but every part supports the unusual security model, and the examples are compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description appropriately explains that the tool returns a Cloud Shell script and that the user must finish with `finops setup azure`. That is enough for an agent to route the user correctly, though it could mention prerequisites or what the script contains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the description does not need to explain parameter semantics. The baseline for no parameters applies, and nothing in the description misleads about inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific purpose: guiding Azure connection while keeping the service-principal secret off the model, and it explicitly distinguishes this flow from connect_aws and connect_gcp. It also says the tool returns a Cloud Shell script for the user to finish in their own terminal, so the tool's role is clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternatives connect_aws and connect_gcp and explains why they are different: those read local credentials, while Azure requires a client secret that must not be pasted into the model. The examples further reinforce when to use it (connecting Azure or asking how to connect an Azure subscription).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connect_gcpConnect GCPA

Connect a Google Cloud billing account from inside your MCP client, no terminal.

Propose-then-confirm and local-only. It reads Google Cloud credentials that already exist on this machine (GOOGLE_APPLICATION_CREDENTIALS or gcloud Application Default Credentials), lists the open billing accounts they can see, and connects the one you choose. It never changes anything in GCP, and credentials stay on this machine.

Call it with no arguments to see the billing accounts available (nothing is stored). Then call it again with billing_account_id set to connect one.

Examples: - "Connect my Google Cloud billing" - "Use my gcloud login to connect GCP"

NameRequiredDescriptionDefault
billing_account_idNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: propose-then-confirm two-phase flow, the exact credential sources it reads, that credentials stay on the machine, and that it never changes anything in GCP. This reconciles the seemingly odd readOnlyHint=false — the write is a local connection record, not a GCP mutation — so there is no annotation contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and the two-step flow before any examples; every sentence carries real information. The trailing example phrasings are mildly redundant with the prose but plausibly useful for matching user intent, so the cost is small.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description partially compensates by saying the no-arg call returns the visible open billing accounts. It does not describe what the connect call returns or what happens on failure (no credentials, multiple/zero accounts), which would matter for a 0-required-param setup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and billing_account_id has no description at all, so the description must carry the load — it does, explaining that omitting it lists accounts and setting it selects the one to connect. The only gap is the expected ID format (e.g. 0X0X0X-XXXXXX-XXXXXX), which an agent must infer from the listing output.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Connect a Google Cloud billing account') plus the scope of what it touches (existing local credentials, open billing accounts). The provider-specific wording lets an agent distinguish it from connect_aws and connect_azure without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit procedural guidance: call with no arguments to list accounts (nothing stored), then call again with billing_account_id set to connect one. It also states the prerequisite — credentials must already exist via GOOGLE_APPLICATION_CREDENTIALS or gcloud ADC — and supplies example user phrasings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estimate_change_costEstimate change costA

Cost preflight for a proposed change: what it costs and whether it fits budget.

Agent-native. Call this BEFORE applying an infrastructure change to get a machine verdict (ok / warn / over_budget / no_budget) plus the monthly and annual cost delta and the budget headroom. It estimates and checks, it never applies anything. Changes nothing. It is not marked read-only only because tf_dir runs terraform plan there, which executes that directory's provider plugins.

Describe the change one of these ways:

  • terraform_plan_json / terraform_plan_file / tf_dir : a Terraform plan

  • helm_diff : output of helm diff upgrade or a values.yaml diff

  • monthly_delta_usd : a known monthly cost delta (escape hatch for any change the estimators don't parse, e.g. "launch a db.r6g.4xlarge")

budget_name selects which budget to check against; default is the first active budget. With no budget configured the verdict is "no_budget" and the cost delta is still returned.

Good triggers: "will this fit my budget", "what will this terraform/helm change cost before I apply it", "cost preflight", "can the agent afford this change". Examples: - "What would this change cost per month?" - "Preflight the cost of this terraform plan"

NameRequiredDescriptionDefault
tf_dirNo
helm_diffNo
budget_nameNo
monthly_delta_usdNo
terraform_plan_fileNo
terraform_plan_jsonNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Directly reconciles with the annotations: it explains that it never mutates anything and that readOnlyHint=false exists only because tf_dir triggers `terraform plan` and its provider plugins. It also discloses the verdict vocabulary (ok/warn/over_budget/no_budget) and the no-budget fallback behavior — context the annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core verdict, then the safety caveat, then the input routes and triggers. Slightly repetitive ('cost preflight' restated in triggers and examples), but every section carries usable signal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by naming the primary return fields: machine verdict, monthly and annual cost delta, and budget headroom. Combined with the mutation disclaimer, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, yet the description documents all six parameters meaningfully: it groups terraform_plan_json/terraform_plan_file/tf_dir/helm_diff as alternative ways to describe the change, explains monthly_delta_usd as an escape hatch with a concrete example, and explains budget_name's default and the no-budget outcome. The only gap is precedence when multiple inputs are supplied.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Cost preflight for a proposed change') and immediately names the scope: estimates and checks budget fit but never applies anything. The distinction from siblings such as get_cost_summary and check_ai_budget is clear from the 'proposed change before apply' framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit timing guidance: 'Call this BEFORE applying an infrastructure change', plus good triggers ('will this fit my budget', 'cost preflight'). It names input routes and an escape hatch, but never explicitly contrasts itself with the sibling cost/budget tools, so the when-not-this-tool case is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_cost_summaryGet cost summaryB
Read-onlyIdempotent

Get total spend summarized by service, account, and region.

Examples: - "How much did we spend last month?" - "Give me an AWS cost summary for January"

NameRequiredDescriptionDefault
accountNo
categoryNo
end_dateNo
providerNo
start_dateNo
granularityNoMONTHLY

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, and open-world behavior. The description adds the aggregation dimensions and example queries, but omits permissions, data freshness, currency, and response shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is brief and front-loaded with the core behavior. The examples are short and earn their place by illustrating realistic usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With six undocumented optional parameters and no output schema, the description does not provide enough detail for an agent to use the filters correctly. It is sufficient for a broad summary call but incomplete for parameterized cost queries.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are six optional parameters with 0% schema description coverage. The description mentions account and examples imply dates and provider, but it does not explain account/category/provider formats, date syntax, or valid granularity values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: get total spend summarized by service, account, and region. It is clear what the tool returns, but it does not explicitly distinguish itself from siblings such as estimate_change_cost.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The examples clearly show when to use the tool, such as asking about last month's spend or an AWS cost summary for January. There are no explicit exclusions or named alternatives, but the usage context is concrete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_connected_providersList connected providersA
Read-onlyIdempotent

List every cloud, SaaS, and LLM provider nable knows, each marked connected or not-configured, plus the active plan. The starting point for "what am I connected to" and for spotting which connector still needs credentials (each not-configured entry names the setup command to run).

Examples: - "Which providers are connected?" - "Is GCP set up yet?"

NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld, and non-destructive, so the safety profile is covered. The description goes beyond them by describing the response contents — every provider appears, tagged connected or not-configured, not-configured rows carry the setup command to run, and the active plan is included.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core sentence is front-loaded and answers what/why in one line, with the examples and setup-command detail following as supporting color. The two example phrasings are mildly redundant with the prose, keeping it just short of maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and no output schema, the description carries the return-value burden itself and does so: it says every known provider is listed, how each is tagged, what the not-configured entries contain, and that the active plan is included. An agent needs nothing else to call it or interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters and the schema is an empty object, so there is nothing for the description to disambiguate. Baseline 4 applies; no parameter semantics are needed or missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (list every cloud, SaaS, and LLM provider) plus the exact per-entry payload (connected / not-configured, active plan). This distinguishes it from the connect_* siblings, which perform configuration rather than enumeration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"The starting point for 'what am I connected to' and for spotting which connector still needs credentials" gives a clear use context, reinforced by two example utterances. It never explicitly says to use connect_aws or nable_setup_status instead for other tasks, so the alternative routing is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nable_setup_statusNable setup statusA
Read-onlyIdempotent

Agent-driven onboarding: what is connected, what credentials are already on this machine, and the exact command to connect each remaining provider.

Call this when the user asks to connect a provider, says setup is incomplete, or asks what they are missing. Detected ambient credentials (gcloud login, env keys, ~/.modal.toml) mean the connect is ONE terminal command with no secrets involved; run it for the user or hand them the command.

Rules for the agent, and they are hard rules:

  • NEVER ask the user to paste an API key or secret into the chat. For paste-a-key providers, have them run the setup command in their own terminal; it deep-links the key page and stores the key locally.

  • Prefer the zero-secret paths: finops connect (batch-connects everything detected) and finops setup gcp / ambient AWS, where no secret ever passes through the conversation.

Examples: - "Connect my GCP costs" - "What providers am I missing?"

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations declaring readOnly, idempotent, open-world, and non-destructive behavior, the description adds critical operational rules: never ask for secrets in chat, prefer ambient credentials, and hand off terminal commands for paste-a-key providers. These are meaningful behavioral constraints an agent could not infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and usage, followed by actionable hard rules and examples. It is somewhat long, but the security and handoff rules justify the length; minor redundancy appears in framing the rules.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description carries the burden well by explaining what the status includes (connected providers, local credentials, exact commands) and how to act on it safely. It provides enough context for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so parameter semantics are inherently minimal. The schema already indicates an empty object, and the description does not need to explain parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states an onboarding/status purpose: what is connected, what credentials are present, and the exact command to connect remaining providers. It is specific about the resource and output, though it does not explicitly distinguish itself from the sibling list_connected_providers tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit triggers (user asks to connect a provider, setup is incomplete, asks what is missing) and examples. It also names preferred zero-secret paths such as `finops connect` and `finops setup gcp`, so an agent knows when and how to use this tool versus direct connection paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

what_can_nable_doWhat can nable doA
Read-onlyIdempotent

Show everything nable can do, tailored to what you've connected.

Call this when the user asks "what can you do?", "what features do you have?", "what should I try first?", "show me what's available", or "help". Always call it right after a user connects their first account, so they see what just became possible. Pass detailed=True to also list the underlying tool names. Examples: - "What can nable do?" - "List your capabilities"

NameRequiredDescriptionDefault
detailedNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as read-only, idempotent, non-destructive, and open-world. The description adds useful behavioral context: results are tailored to connected accounts and include underlying tool names only when detailed=True.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main purpose and usage guidance are front-loaded, and the example phrases are helpful. The repeated examples are slightly redundant, but they reinforce the trigger conditions without obscuring the call semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described in detail. The description covers purpose, invocation timing, and the only parameter, making it complete enough for an agent to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the single parameter is explained in the description: detailed=True lists underlying tool names. That compensates for the schema gap, though it does not describe the default false behavior explicitly beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific capability-discovery function and makes its scope clear: it shows everything nable can do, tailored to connected accounts. This is distinguishable from sibling tools such as cost summaries, provider connections, and policy checks.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit trigger phrases, states when to call it after a user connects their first account, and explains the detailed flag. Alternatives are implicit because this is the dedicated capability-discovery tool among operational siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.12.0
    • Changedcheck_ai_budget1 field changed
      • addedInput schema / properties / session_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Session Id"
        +}
  2. 27 tool updatesv0.8.213
    • Removedaudit_duplicate_spend
    • Removedaudit_terraform_tags
    • Addedcheck_action_policy
    • Addedcheck_ai_budget
    • Addedconnect_aws
    • Addedconnect_azure
    • Addedconnect_gcp
    • Addedestimate_change_cost
    • Removedgenerate_terraform_tag_fixes
    • Addedget_cost_summary
    • Removedget_costs_by_team
    • Removedget_data_transfer_costs
    • Removedget_efficiency_scorecard
    • Removedget_idle_load_balancers
    • Removedget_instance_deep_analysis
    • Removedget_label_costs
    • Removedget_ou_cost_breakdown
    • Removedget_rightsizing_recommendations
    • Addedlist_connected_providers
    • Removedlist_idle_resources
    • Removedlist_pinned_views
    • Addednable_setup_status
    • Removedopen_rightsizing_pr
    • Removedrun_attribution_now
    • Removedscan_waste_patterns
    • Removedverify_savings
    • Addedwhat_can_nable_do
  3. 168 tool updatesv0.8.181
    • Removedacknowledge_anomaly
    • Removedaudit_aws_waste
    • Removedaudit_cloudwatch_logs_ia_opportunities
    • Removedaudit_cloudwatch_metric_cardinality
    • Removedaudit_cloudwatch_orphaned_alarms
    • Addedaudit_duplicate_spend
    • Removedaudit_ebs_snapshot_replication
    • Removedaudit_efs_cross_az_mounts
    • Removedaudit_gcp_waste
    • Removedaudit_nlb_cross_zone_costs
    • Removedaudit_public_ipv4_addresses
    • Removedaudit_rds_manual_snapshots
    • Removedaudit_s3_intelligent_tiering
    • Removedaudit_s3_transfer_acceleration
    • Removedaudit_spot_diversification
    • Removedaudit_textract_environment_waste
    • Removedbenchmark_costs
    • Removedcancel_report_subscription
    • Removedcheck_action_policy
    • Removedcheck_budget_status
    • Removedcheck_connector_health
    • Removedcheck_notification_config
    • Removedcleanup_idle_resources
    • Removedcompare_kubernetes_clusters
    • Removedcompare_providers
    • Removedcreate_anomaly_tickets
    • Removedcreate_api_key
    • Removedcreate_kubernetes_waste_tickets
    • Removedcreate_rightsizing_tickets
    • Removedcreate_scorecard_tickets
    • Removedcreate_ticket
    • Removeddelete_alert_policy
    • Removeddelete_budget
    • Removeddismiss_recommendation
    • Removedestimate_change_cost
    • Removedestimate_helm_diff_cost
    • Removedestimate_terraform_cost
    • Removedexplain_cost_change
    • Removedexplain_recent_cost_drivers
    • Removedexport_board_summary
    • Removedexport_cost_report
    • Removedexport_cost_report_csv
    • Removedfetch_invoice_emails
    • Removedforecast_azure_costs
    • Removedforecast_costs
    • Removedforecast_llm_costs
    • Removedgenerate_account_dashboard
    • Removedget_account_anomalies
    • Removedget_ai_billing_blind_spots
    • Removedget_ai_engineering_report
    • Removedget_ai_kpis
    • Removedget_ai_spend_monitor
    • Removedget_anomalies
    • Removedget_azure_advisor_recommendations
    • Removedget_azure_budgets
    • Removedget_azure_cost_by_dimension
    • Removedget_azure_reservation_utilization
    • Removedget_azure_vm_rightsizing
    • Removedget_bedrock_costs
    • Removedget_business_metrics
    • Removedget_cluster_efficiency
    • Removedget_commitment_analysis
    • Removedget_commitment_coverage_by_tag
    • Removedget_cost_history
    • Removedget_cost_summary
    • Removedget_cost_summary_all_accounts
    • Removedget_cost_trends
    • Removedget_costs_by_service
    • Removedget_credit_status
    • Removedget_databricks_cluster_efficiency
    • Removedget_databricks_costs
    • Removedget_databricks_dbu_breakdown
    • Removedget_databricks_job_costs
    • Removedget_documentdb_costs
    • Removedget_ecr_cleanup_recommendations
    • Removedget_ecs_rightsizing_recommendations
    • Removedget_effective_rate_profile
    • Removedget_focus_costs
    • Removedget_gpu_infra_costs
    • Removedget_helm_release_costs
    • Removedget_idle_rds_instances
    • Removedget_kendra_costs
    • Removedget_kubernetes_cost_trends
    • Removedget_kubernetes_costs
    • Removedget_kubernetes_namespace_breakdown
    • Removedget_langfuse_model_costs
    • Removedget_langfuse_trace_volume
    • Removedget_llm_commitment_analysis
    • Removedget_llm_cost_by_model
    • Removedget_llm_costs
    • Removedget_llm_unit_economics
    • Removedget_llm_unit_economics_full
    • Removedget_marketplace_costs
    • Removedget_nable_roi
    • Removedget_org_cost_summary
    • Removedget_pinned_view
    • Removedget_rds_rightsizing_recommendations
    • Removedget_recommendation_learning
    • Removedget_recommendation_quality
    • Removedget_resource_cost_breakdown_aws
    • Removedget_resource_cost_breakdown_azure
    • Removedget_ri_waste_detail
    • Removedget_s3_incomplete_multipart_uploads
    • Removedget_saas_spend_summary
    • Removedget_savings_ledger
    • Removedget_savings_plan_showback
    • Removedget_savings_summary
    • Removedget_service_cost
    • Removedget_storage_info
    • Removedget_tableau_connection_info
    • Removedget_tag_cost_breakdown_cur
    • Removedget_team_scorecards
    • Removedget_textract_costs
    • Removedget_top_cost_drivers
    • Removedget_top_spending_accounts
    • Removedget_total_spend_all_sources
    • Removedget_traffic_cost_breakdown
    • Removedget_unit_economics
    • Removedget_view
    • Removedget_workload_costs
    • Removedidentify_nonprod_scheduling_opportunities
    • Removedlist_accounts
    • Removedlist_active_services
    • Removedlist_alert_policies
    • Removedlist_api_keys
    • Removedlist_aws_accounts
    • Removedlist_budgets
    • Removedlist_connected_providers
    • Removedlist_kubernetes_contexts
    • Removedlist_org_accounts
    • Removedlist_profiles
    • Removedlist_report_subscriptions
    • Removedlist_savings_recommendations
    • Removedlist_vault_credentials
    • Removedlist_views
    • Removedmark_recommendation_acted_on
    • Removedopen_terraform_tag_pr
    • Removedoptimize_ai_spend
    • Removedpin_view
    • Removedpublish_cost_report_to_notion
    • Removedpush_to_n8n
    • Removedpush_weekly_insight
    • Removedrecommend_bedrock_model_routing
    • Removedrecommend_database_savings_plans
    • Removedrecommend_lambda_snapstart
    • Removedrecommend_spot_adoption
    • Removedrevoke_api_key
    • Removedrun_full_cost_audit
    • Removedscan_cloudwatch_waste
    • Removedscan_graviton_migration_opportunities
    • Removedscan_lambda_concurrency_waste
    • Removedscan_s3_bucket_key_opportunities
    • Changedscan_waste_patterns4 fields changed
      • addedInput schema / properties / account_id / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / account_id / default
        Added value: +null
      • removedInput schema / properties / account_id / type
        Removed value: -"string"
      • removedInput schema / required
        Removed value: -[
        -  "account_id"
        -]
    • Removedsend_digest_now
    • Removedsend_onboarding_email
    • Removedsend_report_now
    • Removedsend_weekly_digest_now
    • Removedset_alert_policy
    • Removedset_budget
    • Removedset_business_metrics
    • Removedslice_costs
    • Removedstart_dashboard_server
    • Removedsubscribe_to_report
    • Removedsync_budgets_from_yaml
    • Removedtake_snapshot_now
    • Removedunpin_view
    • Removedwhat_can_nable_do
    • Removedwhoami
  4. 182 tool updatesv0.8.96
    • First observedacknowledge_anomaly
    • First observedaudit_aws_waste
    • First observedaudit_cloudwatch_logs_ia_opportunities
    • First observedaudit_cloudwatch_metric_cardinality
    • First observedaudit_cloudwatch_orphaned_alarms
    • First observedaudit_ebs_snapshot_replication
    • First observedaudit_efs_cross_az_mounts
    • First observedaudit_gcp_waste
    • First observedaudit_nlb_cross_zone_costs
    • First observedaudit_public_ipv4_addresses
    • First observedaudit_rds_manual_snapshots
    • First observedaudit_s3_intelligent_tiering
    • First observedaudit_s3_transfer_acceleration
    • First observedaudit_spot_diversification
    • First observedaudit_terraform_tags
    • First observedaudit_textract_environment_waste
    • First observedbenchmark_costs
    • First observedcancel_report_subscription
    • First observedcheck_action_policy
    • First observedcheck_budget_status
    • First observedcheck_connector_health
    • First observedcheck_notification_config
    • First observedcleanup_idle_resources
    • First observedcompare_kubernetes_clusters
    • First observedcompare_providers
    • First observedcreate_anomaly_tickets
    • First observedcreate_api_key
    • First observedcreate_kubernetes_waste_tickets
    • First observedcreate_rightsizing_tickets
    • First observedcreate_scorecard_tickets
    • First observedcreate_ticket
    • First observeddelete_alert_policy
    • First observeddelete_budget
    • First observeddismiss_recommendation
    • First observedestimate_change_cost
    • First observedestimate_helm_diff_cost
    • First observedestimate_terraform_cost
    • First observedexplain_cost_change
    • First observedexplain_recent_cost_drivers
    • First observedexport_board_summary
    • First observedexport_cost_report
    • First observedexport_cost_report_csv
    • First observedfetch_invoice_emails
    • First observedforecast_azure_costs
    • First observedforecast_costs
    • First observedforecast_llm_costs
    • First observedgenerate_account_dashboard
    • First observedgenerate_terraform_tag_fixes
    • First observedget_account_anomalies
    • First observedget_ai_billing_blind_spots
    • First observedget_ai_engineering_report
    • First observedget_ai_kpis
    • First observedget_ai_spend_monitor
    • First observedget_anomalies
    • First observedget_azure_advisor_recommendations
    • First observedget_azure_budgets
    • First observedget_azure_cost_by_dimension
    • First observedget_azure_reservation_utilization
    • First observedget_azure_vm_rightsizing
    • First observedget_bedrock_costs
    • First observedget_business_metrics
    • First observedget_cluster_efficiency
    • First observedget_commitment_analysis
    • First observedget_commitment_coverage_by_tag
    • First observedget_cost_history
    • First observedget_cost_summary
    • First observedget_cost_summary_all_accounts
    • First observedget_cost_trends
    • First observedget_costs_by_service
    • First observedget_costs_by_team
    • First observedget_credit_status
    • First observedget_data_transfer_costs
    • First observedget_databricks_cluster_efficiency
    • First observedget_databricks_costs
    • First observedget_databricks_dbu_breakdown
    • First observedget_databricks_job_costs
    • First observedget_documentdb_costs
    • First observedget_ecr_cleanup_recommendations
    • First observedget_ecs_rightsizing_recommendations
    • First observedget_effective_rate_profile
    • First observedget_efficiency_scorecard
    • First observedget_focus_costs
    • First observedget_gpu_infra_costs
    • First observedget_helm_release_costs
    • First observedget_idle_load_balancers
    • First observedget_idle_rds_instances
    • First observedget_instance_deep_analysis
    • First observedget_kendra_costs
    • First observedget_kubernetes_cost_trends
    • First observedget_kubernetes_costs
    • First observedget_kubernetes_namespace_breakdown
    • First observedget_label_costs
    • First observedget_langfuse_model_costs
    • First observedget_langfuse_trace_volume
    • First observedget_llm_commitment_analysis
    • First observedget_llm_cost_by_model
    • First observedget_llm_costs
    • First observedget_llm_unit_economics
    • First observedget_llm_unit_economics_full
    • First observedget_marketplace_costs
    • First observedget_nable_roi
    • First observedget_org_cost_summary
    • First observedget_ou_cost_breakdown
    • First observedget_pinned_view
    • First observedget_rds_rightsizing_recommendations
    • First observedget_recommendation_learning
    • First observedget_recommendation_quality
    • First observedget_resource_cost_breakdown_aws
    • First observedget_resource_cost_breakdown_azure
    • First observedget_ri_waste_detail
    • First observedget_rightsizing_recommendations
    • First observedget_s3_incomplete_multipart_uploads
    • First observedget_saas_spend_summary
    • First observedget_savings_ledger
    • First observedget_savings_plan_showback
    • First observedget_savings_summary
    • First observedget_service_cost
    • First observedget_storage_info
    • First observedget_tableau_connection_info
    • First observedget_tag_cost_breakdown_cur
    • First observedget_team_scorecards
    • First observedget_textract_costs
    • First observedget_top_cost_drivers
    • First observedget_top_spending_accounts
    • First observedget_total_spend_all_sources
    • First observedget_traffic_cost_breakdown
    • First observedget_unit_economics
    • First observedget_view
    • First observedget_workload_costs
    • First observedidentify_nonprod_scheduling_opportunities
    • First observedlist_accounts
    • First observedlist_active_services
    • First observedlist_alert_policies
    • First observedlist_api_keys
    • First observedlist_aws_accounts
    • First observedlist_budgets
    • First observedlist_connected_providers
    • First observedlist_idle_resources
    • First observedlist_kubernetes_contexts
    • First observedlist_org_accounts
    • First observedlist_pinned_views
    • First observedlist_profiles
    • First observedlist_report_subscriptions
    • First observedlist_savings_recommendations
    • First observedlist_vault_credentials
    • First observedlist_views
    • First observedmark_recommendation_acted_on
    • First observedopen_rightsizing_pr
    • First observedopen_terraform_tag_pr
    • First observedoptimize_ai_spend
    • First observedpin_view
    • First observedpublish_cost_report_to_notion
    • First observedpush_to_n8n
    • First observedpush_weekly_insight
    • First observedrecommend_bedrock_model_routing
    • First observedrecommend_database_savings_plans
    • First observedrecommend_lambda_snapstart
    • First observedrecommend_spot_adoption
    • First observedrevoke_api_key
    • First observedrun_attribution_now
    • First observedrun_full_cost_audit
    • First observedscan_cloudwatch_waste
    • First observedscan_graviton_migration_opportunities
    • First observedscan_lambda_concurrency_waste
    • First observedscan_s3_bucket_key_opportunities
    • First observedscan_waste_patterns
    • First observedsend_digest_now
    • First observedsend_onboarding_email
    • First observedsend_report_now
    • First observedsend_weekly_digest_now
    • First observedset_alert_policy
    • First observedset_budget
    • First observedset_business_metrics
    • First observedslice_costs
    • First observedstart_dashboard_server
    • First observedsubscribe_to_report
    • First observedsync_budgets_from_yaml
    • First observedtake_snapshot_now
    • First observedunpin_view
    • First observedverify_savings
    • First observedwhat_can_nable_do
    • First observedwhoami

TDQS

A3.9/5.0

Scored across 10 tools

Disambiguation3/5

Most tools are distinct: cost summary, cost preflight, AI budget check, and action policy check target separate decisions. However, the connection/onboarding story overlaps: connect_aws/gcp/azure, nable_setup_status, and list_connected_providers can all plausibly be selected when a user asks to connect or inspect providers. Descriptions help, but boundaries are not crisp enough for perfect tool selection.

Naming Consistency3/5

Most tools use snake_case and several follow a verb_noun pattern (connect_aws, get_cost_summary, estimate_change_cost, list_connected_providers). But what_can_nable_do is phrased as a question and nable_setup_status uses a prefixed noun style, breaking a predictable convention. Readable overall, but not a clean uniform pattern.

Tool Count5/5

Ten tools is a well-scoped set for a FinOps MCP server covering provider connection, cost visibility, budget/policy guardrails, and onboarding assistance. Each tool maps to a plausible agent workflow, and the count is neither thin nor bloated.

Completeness3/5

Core workflows are present: connect major clouds, summarize spend, preflight change cost, check AI budget, check action policy, and inspect setup/connected providers. But there are notable gaps for a FinOps server: no budget CRUD or budget listing, no disconnect/unlink operation, and no cost history/forecast/anomaly tooling. Agents can work around some gaps, but the lifecycle is not fully covered.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    An MCP server for unified cost tracking and analysis across AWS, OpenAI, and Anthropic. It enables users to query expenditures, compare costs across providers, and analyze usage trends through natural language.
    10
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables natural language analysis of AWS costs, automated FinOps waste audits, and budget monitoring across multiple profiles and regions while keeping credentials secure locally.
    184
    MIT