Quickstart

Quickstart

Install nable, point it at your AI editor, then ask about your cloud spend. You only need one provider to start.

What you need

  • Python 3.10+ with pip
  • Claude Desktop or Cursor (or any MCP-compatible editor)
  • Read-only credentials for at least one cloud account (AWS, Azure, or GCP)
1

Install and connect, one command

uvx --from finops-mcp finops welcome

uv fetches a matching Python and runs the setup wizard. No PATH setup, no separate install step. Want a look first? uvx --from finops-mcp finops welcome --demo runs it on sample data. Already on Python 3.10+? pip install -U finops-mcp && finops welcome. No uv? brew install uv.

2

Prefer a permanent install? (optional)

uv tool install finops-mcp && uv tool update-shell

Installs the finops commands on your PATH so you can run finops welcome, finops doctor, and the rest directly. Open a new terminal after update-shell. Then fully quit and reopen your editor.

Prefer manual MCP setup? Add this to your editor's config:

// Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json
// Cursor: ~/.cursor/mcp.json
{
  "mcpServers": {
    "finops": { "command": "finops-mcp" }
  }
}

Tip: replace finops-mcp with the full path from which finops-mcp. macOS GUI apps inherit a minimal PATH and may not find the command otherwise.

3

Ask your first question

In Claude Desktop or Cursor, type:

"What are my top 5 AWS cost drivers this month, and did anything spike unexpectedly?"

nable breaks down your spend by service, flags anomalies, and explains what changed. No SQL, no dashboards.

Security note: Credentials are stored in your OS keyring (macOS Keychain, Windows Credential Manager, or libsecret on Linux). They never leave your machine.

Detailed installation

1

Install and run the welcome wizard

uvx --from finops-mcp finops welcome

The welcome command walks you through connecting Claude and your first cloud account, then shows your first cost number in the terminal. Takes about 5 minutes (including IAM setup). uv fetches a matching Python automatically and needs no PATH setup. Already on Python 3.10+? pip install -U finops-mcp && finops welcome works too.

2

Or connect providers individually

# Pick whichever you care about most:
finops setup aws
finops setup azure
finops setup gcp

The wizard creates a read-only IAM policy, walks through the API key, and stores credentials in your OS keyring. You don't need all 17 connectors. One is enough to start.

3

Add nable to your AI editor's MCP config

// Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json
// Cursor: ~/.cursor/mcp.json
{
  "mcpServers": {
    "finops": { "command": "finops-mcp" }
  }
}

Run finops setup to have this written automatically, or paste it manually. Then fully quit and reopen your editor. Most clients only read config at startup.

4

Verify everything is connected

finops-doctor
✓ aws    configured
✓ datadog configured
– azure   not configured

If a provider shows red, re-run finops setup <provider> or check the troubleshooting section.

5

Ask your first question

In Claude Desktop or Cursor, type:

"What are my top 5 AWS cost drivers this month, and did anything spike unexpectedly?"

nable will break down your spend by service, flag anomalies, and explain what changed. No SQL, no dashboards.

Security note: Credentials are encrypted with Fernet and stored in your OS keyring (macOS Keychain, Windows Credential Manager, or libsecret on Linux). They never leave your machine.

Activate your Team license

After purchase, your license key is emailed to you. Keys start with FINOPS-1-. Run one command and it handles everything.

1

Run the license command with your key

finops setup license FINOPS-1-your-key-here

This validates the key, stores it in your OS keyring, and writes it directly into your Claude Desktop config. No manual JSON editing.

2

Restart Claude Desktop. Team features unlock immediately.

Check your status anytime: finops setup license-status

AI client setup

Add the MCP server to your AI client's config. You only need to do this once.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "finops": {
      "command": "finops-mcp"
    }
  }
}

Note: if you used finops setup, this was configured automatically with the correct path. If editing manually, use the full path from which finops-mcp instead of the bare command name.

Cursor

Settings → MCP → Add server, or edit ~/.cursor/mcp.json

{
  "mcpServers": {
    "finops": { "command": "finops-mcp" }
  }
}

Tip: replace finops-mcp with the full path from which finops-mcp. macOS GUI apps inherit a minimal PATH and may not find the command otherwise.

Windsurf

Edit ~/.codeium/windsurf/mcp_config.json

{
  "mcpServers": {
    "finops": { "command": "finops-mcp" }
  }
}

Tip: replace finops-mcp with the full path from which finops-mcp. macOS GUI apps inherit a minimal PATH and may not find the command otherwise.

OpenAI Codex / other MCP clients

Run the server manually and point your client at the stdio transport.

finops-mcp # listens on stdio

Cloud Providers

aws AWS

Connects to Cost Explorer for spend data, and CloudWatch for rightsizing metrics. Supports IAM keys, IAM Identity Center SSO, and cross-account role assumption.

Cost Explorer must be enabled in your AWS account before the API will work. Go to Billing → Cost Explorer → Enable. It takes up to 24 hours to activate on a new account.

nable works with whatever permissions you're comfortable giving it. Start with Cost Explorer read-only and you get cost queries, anomaly detection, and budget tracking. Add the audit permissions when you're ready and you unlock the deep waste scanner.

Bare bones
Full audit

What you get

  • Cost queries across all services
  • Anomaly detection
  • Budget alerts and soft checks
  • Savings plan coverage
  • Forecasting

Everything above, plus

  • Deep waste audit (10 pattern types)
  • CloudWatch rightsizing per instance
  • Idle NAT / EIP / EBS detection
  • Lambda memory analysis
  • S3 storage class optimization
ce:GetCostAndUsage
ce:GetSavingsPlans*
ce:GetReservation*
sts:GetCallerIdentity
# everything on the left, plus:
cloudwatch:GetMetricData
ec2:Describe{Instances,Volumes,
  Snapshots,Addresses,NatGateways}
rds:Describe{DBInstances,DBSnapshots}
lambda:ListFunctions
logs:DescribeLogGroups
s3:ListAllMyBuckets
compute-optimizer:Get*
Permissions are read-only except one: logs:PutRetentionPolicy, included for optional auto-remediation of infinite-retention log groups. nable makes no other writes, and destructive cleanup (delete or terminate) requires explicitly setting FINOPS_CLEANUP_ENABLED=true. Run finops setup aws --iam-template to generate a least-privilege CloudFormation policy for either tier.
1

Create an IAM user with the permissions above, or use an existing SSO role.

2
finops setup aws
3

Enter your Access Key ID and Secret Access Key when prompted. For SSO, enter your profile name.

Manual env vars (alternative to wizard)

AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=your-secret
AWS_DEFAULT_REGION=us-east-1  # CE requires us-east-1

az Azure

Connects to Azure Cost Management API. Supports Service Principal (recommended for automation) and device code flow (interactive login).

Required Azure role

Cost Management Reader(scoped to your Subscription or Management Group)
1

Create a Service Principal: az ad sp create-for-rbac --name finops-mcp --role "Cost Management Reader" --scopes /subscriptions/YOUR_SUB_ID

2
finops setup azure
3

Enter Tenant ID, Client ID, Client Secret, and Subscription ID when prompted.

Manual env vars

AZURE_TENANT_ID=your-tenant-id
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
AZURE_SUBSCRIPTION_ID=your-subscription-id

gcp GCP

Primary path: BigQuery billing export (recommended, richer data). Fallback: Cloud Billing API. Both use a service account JSON key stored encrypted in your vault.

Required IAM roles

roles/billing.viewerBilling API access
roles/bigquery.dataViewer(only if using BigQuery export)
roles/bigquery.jobUser(only if using BigQuery export)
1

Create a service account in GCP Console → IAM → Service Accounts. Assign roles above. Download the JSON key file.

2

(Recommended) Enable billing export to BigQuery: Billing → Billing export → BigQuery export.

3
finops setup gcp
4

Paste the path to your JSON key file and your GCP Project ID when prompted.

Manual env vars

GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
GCP_PROJECT_ID=my-project-123
GCP_BIGQUERY_DATASET=billing_export  # if using BQ export

SaaS Tools

dd Datadog

Real cost data via the Usage Metering API v2. Returns host counts, APM hosts, log ingestion, and dollar amounts where available. Supports EU site.

1

Go to Organization Settings → API Keys → New Key. Name it finops-mcp.

2

Go to Organization Settings → Application Keys → New Key.

3
finops setup datadog
DATADOG_API_KEY=your-api-key
DATADOG_APP_KEY=your-app-key
DATADOG_SITE=datadoghq.com  # or datadoghq.eu

sf Snowflake

Queries ACCOUNT_USAGE.METERING_HISTORY for real credit consumption. Set your contract credit price to convert to USD.

Required privilege

IMPORTED PRIVILEGES on database SNOWFLAKE(grants access to ACCOUNT_USAGE schema)
1

Create a read-only role and user: GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE TO ROLE finops_role;

2
finops setup snowflake
SNOWFLAKE_ACCOUNT=xy12345.us-east-1
SNOWFLAKE_USER=finops_user
SNOWFLAKE_PASSWORD=your-password
SNOWFLAKE_WAREHOUSE=COMPUTE_WH
SNOWFLAKE_CREDIT_PRICE=3.00  # your contract rate per credit
SNOWFLAKE_ROLE=ACCOUNTADMIN  # optional, defaults to ACCOUNTADMIN

gh GitHub

Returns paid Actions minutes used and Copilot seat counts. Requires org-level access.

1

Go to Settings → Developer settings → Personal access tokens → Fine-grained tokens. Select your org. Set permissions: read:billing, read:org.

2
finops setup github
GITHUB_TOKEN=github_pat_...
GITHUB_ORGS=your-org-name

str Stripe

Returns actual fees paid to Stripe via the Balance Transactions API. Use a restricted key with no write permissions needed.

1

Go to Stripe Dashboard → Developers → API Keys → Create restricted key. Enable: Balance → Read only.

2
finops setup stripe
STRIPE_SECRET_KEY=sk_live_...

tw Twilio

Paginated usage records with real billing amounts. Uses your main Account SID and Auth Token.

1

Find your Account SID and Auth Token on the Twilio Console homepage.

2
finops setup twilio
TWILIO_ACCOUNT_SID=ACxxxxxx
TWILIO_AUTH_TOKEN=your-auth-token

mg MongoDB Atlas

Invoice API with line-item breakdown. Uses Digest Auth with an org-level API key.

1

Go to Atlas → Access Manager → Organization Access → API Keys → Create API Key. Role: Organization Billing Viewer.

2
finops setup mongodb
MONGODB_ATLAS_PUBLIC_KEY=your-public-key
MONGODB_ATLAS_PRIVATE_KEY=your-private-key
MONGODB_ATLAS_ORG_IDS=your-org-id

cf Cloudflare

Billing history and active subscriptions via the Cloudflare API.

1

Go to Cloudflare Dashboard → My Profile → API Tokens → Create Token. Use the "Read billing info" template.

2
finops setup cloudflare
CLOUDFLARE_API_TOKEN=your-api-token
CLOUDFLARE_ACCOUNT_ID=your-account-id

vcl Vercel

Invoice API, requires a Vercel Enterprise plan. Returns invoices with line items. Returns a descriptive message if no invoice data is available.

Invoice data is only available on Enterprise plans. Vercel Pro or Hobby plans won't return billing data via the API.
1

Go to Vercel Dashboard → Settings → Tokens → Create. Scope: Full Account.

2
finops setup vercel
VERCEL_TOKEN=your-token
VERCEL_TEAM_ID=team_xxxxxxx  # optional, for team accounts

pd PagerDuty

Returns seat count and user data. For actual dollar amounts, use the Invoice email parser, as PagerDuty doesn't expose billing amounts via API.

1

Go to My Profile → User Settings → Create API User Token. Read-only access is sufficient.

2

Set the env var manually or run finops setup (interactive mode) and select PagerDuty.

PAGERDUTY_API_TOKEN=your-token

nr New Relic

Returns data ingest (GB) and full platform user counts. Set your contract ingest price to convert to USD.

1

Go to New Relic → API Keys → Create key. Type: User key.

2

Set the env vars manually or run finops setup (interactive mode) and select New Relic.

NEW_RELIC_API_KEY=NRAK-...
NEW_RELIC_ACCOUNT_ID=1234567
NEW_RELIC_INGEST_PRICE_PER_GB=0.35  # your contract rate

lf Langfuse

Tracks LLM observability costs via the Langfuse Daily Metrics API. Returns model cost, token usage, and trace volume so you can see how much each model and project is actually costing you.

1

Go to Langfuse → Settings → API Keys and create a new key pair. Copy the public and secret keys.

2
finops setup langfuse
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://cloud.langfuse.com  # optional, defaults to cloud.langfuse.com

db Databricks

DBU consumption and cost data from the Databricks REST API. Surfaces cluster-level spend, job costs, workspace totals, idle clusters, missing auto-termination, and autoscale efficiency. Uses the Billable Usage Download API when an account ID is set; otherwise estimates from cluster uptime and job run history.

1

In your Databricks workspace, go to Settings → Developer → Access Tokens → Generate new token. For service principals, use the OAuth M2M flow instead.

2
finops setup databricks
DATABRICKS_HOST=https://adb-1234567890.1.azuredatabricks.net
DATABRICKS_TOKEN=dapi...
DATABRICKS_ACCOUNT_ID=your-account-id  # optional: enables exact billing via the Usage Download API
DATABRICKS_DBU_PRICE=0.40  # optional, override with your contract rate (default $0.40/DBU)

Cost estimation note

Without DATABRICKS_ACCOUNT_ID, costs are estimated from cluster uptime and job run duration using list DBU rates. Set your account ID and an account-level token for exact figures from the Billable Usage API. Override DATABRICKS_DBU_PRICE with your negotiated rate for accurate dollar amounts.

Available tools

get_databricks_costsTotal spend by service type for a date range
get_databricks_dbu_breakdownDBU by cluster type, top 10 clusters and jobs, savings tip if all-purpose clusters dominate
get_databricks_cluster_efficiencyAudit every cluster for missing auto-termination, idle time, fixed vs autoscale, and missing tags
get_databricks_job_costsTop N most expensive job runs with DBU, duration, and estimated cost

Invoice email parsing

For vendors with no billing API (PagerDuty, New Relic, GitHub Enterprise, etc.), nable can connect to your billing inbox via IMAP, parse PDF and HTML invoices, and extract real dollar amounts automatically.

Create a dedicated billing@yourcompany.com mailbox and forward all vendor invoices there. This keeps it clean and avoids scanning your main inbox.
1

Enable IMAP access on your mailbox (Gmail: Settings → See all settings → Forwarding and POP/IMAP).

2

If using Gmail, create an App Password (requires 2FA): Google Account → Security → App passwords.

3

Set the env vars below in your MCP config or shell environment. Run finops setup to store them securely in the vault.

FINOPS_IMAP_HOST=imap.gmail.com
FINOPS_IMAP_PORT=993
FINOPS_IMAP_USER=billing@yourcompany.com
FINOPS_IMAP_PASSWORD=your-app-password

Alerts & Automation

sl Slack alerts

Sends anomaly alerts and daily digests to a Slack channel. Uses an incoming webhook, no bot scopes needed.

1

Go to api.slack.com/apps → Create app → Incoming Webhooks → Add webhook to workspace. Select your #finops channel.

2

Copy the webhook URL and add to your env:

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../...

ms Microsoft Teams alerts

Sends anomaly alerts and daily digests via an Incoming Webhook connector.

1

In Teams, go to your channel → ⋯ → Connectors → Incoming Webhook → Configure. Copy the webhook URL.

TEAMS_WEBHOOK_URL=https://yourorg.webhook.office.com/webhookb2/...

Weekly email digest Team

Sends a standalone HTML email every Monday at 09:00 UTC with last week's spend, anomalies, and rightsizing recommendations. No AI client session required. Fires from the scheduler.

FINOPS_SMTP_HOST=smtp.gmail.com
FINOPS_SMTP_PORT=587
FINOPS_SMTP_USER=you@yourcompany.com
FINOPS_SMTP_PASSWORD=your-app-password
FINOPS_DIGEST_TO=team@yourcompany.com
FINOPS_WEEKLY_CRON="0 9 * * 1"  # optional - default Mon 09:00 UTC

Auto-ticketing Team

When a high or medium-severity anomaly is detected, nable automatically creates a ticket in your tracker. Configure one or more. The first configured is used by default.

Jira

Create an API token at id.atlassian.com → Security → API tokens.

JIRA_URL=https://yourorg.atlassian.net
JIRA_EMAIL=you@yourcompany.com
JIRA_API_TOKEN=your-api-token
JIRA_PROJECT_KEY=FINOPS

Linear

Create an API key at Linear → Settings → API → Personal API keys.

LINEAR_API_KEY=lin_api_...
LINEAR_TEAM_ID=your-team-id

GitHub Issues

Needs a fine-grained token with issues: write on the target repo.

GITHUB_TOKEN=github_pat_...
GITHUB_ISSUES_REPO=yourorg/finops-alerts

sl Slack bot

A persistent bot you can talk to directly in Slack. Just DM @nable or mention it in any channel. It calls the same nable tools under the hood and responds with cost analysis, anomaly summaries, rightsizing recommendations, and more. Different from the webhook alerts above: this is conversational.

Free. Install the Slack extra: pip install finops-mcp[slack]
1

Go to api.slack.com/apps → Create app → From scratch. Name it nable.

2

Under OAuth & Permissions, add bot token scopes: app_mentions:read, chat:write, im:history, im:read. Install the app to your workspace and copy the Bot User OAuth Token.

3

Under Socket Mode, enable it and generate an App-Level Token with the connections:write scope. Copy that token too.

4

Under Event Subscriptions, enable events and subscribe to app_mention and message.im.

5

Set your env vars and start the bot:

SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
ANTHROPIC_API_KEY=sk-ant-...
SLACK_DAILY_CHANNEL=#finops  # optional - sends daily digest at 09:00 UTC
finops-slack

Uses Socket Mode, no public URL or reverse proxy needed. Keep it running in the background (systemd, screen, or Docker).


gh PR cost comments

Automatically posts a cost estimate on GitHub pull requests when infrastructure files change (Terraform, CloudFormation, CDK, Helm). The comment is updated, not duplicated, on each push. Only fires if the estimated impact exceeds your configured threshold.

Free. Install the PR comments extra: pip install finops-mcp[pr-comments]
1

Create a GitHub fine-grained personal access token with pull_requests: write on the target repos.

2

Set your env vars and start the webhook server:

GITHUB_TOKEN=github_pat_...
GITHUB_WEBHOOK_SECRET=your-secret  # recommended - validates webhook payloads
PR_COST_THRESHOLD_USD=10  # skip comment if impact is under $10/mo
PR_WEBHOOK_PORT=8080  # optional - default 8080
finops-pr-webhook
3

In your GitHub repo, go to Settings → Webhooks → Add webhook. Set the payload URL to http://your-host:8080/webhook/github, content type to application/json, and choose the Pull requests event.

Cost estimates are factual and account-aware. The comment shows current instance counts, estimated monthly delta, and your effective discount rate (auto-detected from Cost Explorer). No editorial commentary.

Idle resource cleanup

Scans for AWS resources that are running but not being used: unattached EBS volumes, unassociated Elastic IPs, stale snapshots, stopped EC2 instances, and load balancers with no healthy targets. Cleanup actions are opt-in and always dry-run by default.

Cleanup is disabled by default. Set FINOPS_CLEANUP_ENABLED=true to enable delete/terminate actions. Without it, the scan tool works but cleanup returns a dry-run preview only.

Example workflow in Claude / Cursor

# Step 1 - see what's idle
list_idle_resources(resource_types=["ebs","eip"], min_idle_days=90)

# Step 2 - preview what cleanup would do (dry_run=True by default)
cleanup_idle_resources(resource_ids=["vol-abc123","vol-def456"], dry_run=True)

# Step 3 - actually clean up
cleanup_idle_resources(resource_ids=["vol-abc123","vol-def456"], dry_run=False)

Protected resource tags

Resources tagged with any of the following are never touched, regardless of idle status:

env=prod   protected=true   do-not-delete=true   finops-skip=true

Override the default protected tag set via env:

FINOPS_CLEANUP_ENABLED=true
FINOPS_PROTECTED_TAGS=env=prod,protected=true,keep=yes  # comma-separated key=value pairs
Every cleanup action, including dry runs, is appended to ~/.finops-mcp/cleanup_audit.jsonl for auditing.

Intelligence

What nable actually does

nable isn't just a connector that pipes your billing data into an AI. It runs active analysis (anomaly detection, CloudWatch-based rightsizing, waste pattern scanning, and commitment modeling) and surfaces the output as MCP tools your AI editor can query, reason about, and act on.


AWS deep audit

The intent here is to give you two tools side by side: AWS Compute Optimizer for standard rightsizing, and nable's audit for the deeper layer underneath it. Optimizer will tell you to downsize an instance. nable will also tell you the EBS volume attached to it is gp2, the snapshot from 6 months ago is still accruing charges, and the CloudTrail trail recording data events in every region is costing you $400/mo nobody noticed.

The patterns below are just what ships out of the box. The audit engine is built to be extended, and the tools are designed to be composed: ask your AI editor to "find every dollar of waste in us-east-1" and it will pull Compute Optimizer, run the deep audit, and cross-reference both.

PatternWhat it catches
gp2 → gp3
EBS volumes on gp2. Same performance, 20% cheaper on gp3
Unattached EBS
Volumes not mounted to any instance, paying for provisioned GB
Orphaned snapshots
EBS snapshots >30 days old with no AMI reference
Unassociated EIPs
Elastic IPs not attached to anything. $3.60/mo each, silent
Idle NAT Gateways
<1 GB/day throughput over 7 days. $32/mo base charge wasted
ChargedBackup
RDS backup retention >7 days, accumulates silently
CloudTrail data events
Data events ($2/100k) enabled across all regions unnecessarily
Infinite log retention
CloudWatch Log Groups with no retention policy, grows forever
S3 storage class
Buckets in STANDARD with low access, only flagged when storage savings exceed Intelligent-Tiering's monitoring cost ($0.0025/1k objects/mo). Recommends STANDARD-IA for infrequent-access patterns instead.
Lambda memory
Configured memory >2× p99 actual usage, direct billing waste

Usage in Claude / Cursor

# Full audit across all regions
audit_aws_waste()

# Target specific checks and region
audit_aws_waste(regions=["us-east-1"], checks=["ebs","nat","rds_backups"])

# Deep CloudWatch analysis for a specific instance
get_instance_deep_analysis(instance_id="i-0abc123", lookback_days=14)

# Scan all log groups for missing retention policies
scan_cloudwatch_waste()
Results are sorted by estimated monthly savings. Each finding includes resource ID, region, waste type, severity, and a plain-English explanation you can act on immediately.

Anomaly detection

Multi-signal detection using z-score, CUSUM drift, and day-of-week seasonal normalisation. When something spikes, nable drills into Cost Explorer by tag and tells you which team, environment, or service drove it, and by how much.

get_anomaliesAll anomalies across every connected provider, last 7-30 days
get_account_anomaliesPer-account breakdown, useful for multi-account AWS orgs
acknowledge_anomalyMark as known / expected so it stops surfacing in digests
create_anomaly_ticketsAuto-file Jira / Linear / GitHub issues for unacknowledged anomalies
Slack and Teams alerts fire automatically when a new anomaly is detected, no polling needed. Configure SLACK_WEBHOOK_URL or TEAMS_WEBHOOK_URL to enable.

Rightsizing

Combines AWS Compute Optimizer recommendations with nable's own CloudWatch analysis. Surfaces instances where actual CPU / memory / connection utilization is consistently below the provisioned level, with a specific recommended type and estimated savings.

get_rightsizing_recommendationsEC2, RDS, and Lambda rightsizing in one call
create_rightsizing_ticketsAuto-file tickets for the top N recommendations by savings
get_instance_deep_analysisPer-instance CloudWatch p95/p99 utilization deep dive

Commitment analysis Team

Models Savings Plans and Reserved Instance coverage against your actual usage patterns. Shows your current effective discount rate, coverage gaps, and what you'd save by purchasing additional commitments, with ROI projections by term length.

get_commitment_analysisCurrent coverage, gaps, and purchase recommendations
get_commitment_coverage_by_tagCoverage breakdown per team / environment / service tag
get_effective_rate_profileYour blended and unblended effective rate vs on-demand
get_savings_plan_showbackSP + RI savings attributed back to each team by tag (CUR required)

Savings Plan showback by team

Savings Plans are purchased at the payer account level. By default there is no way to know which team benefited from a discount. Your bill shows one blended rate and tools like CloudHealth, Apptio, and AWS Cost Explorer all approximate the allocation. nable reads two fields from CUR that most tools ignore:

savingsplan_savings_plan_effective_cost  - what the resource actually cost under SP rates
pricing_public_on_demand_cost  - what it would have cost on-demand

The difference is the real dollar savings that resource captured from the SP. Grouped by a resource tag (e.g. team), this gives each team their effective discount rate and savings captured. No tool below the $50K/yr tier offers this at line-item granularity.

Approximation notice

Like CloudHealth and Apptio, this is an approximation. AWS applies SP discounts using internal logic that is not fully exposed in the CUR. Specifically: family-based SP allocation order (AWS picks which resources to cover first) is not deterministic from CUR data alone, and SP amortization timing can shift costs across billing periods by a few percent. Results will be within ~2–5% of the true allocation for most workloads, and significantly more accurate than tools that rely solely on Cost Explorer blended rates. Treat showback figures as a strong signal for team accountability, not an accounting-grade ledger entry.

Example output
payments  effective_cost: $8,240  on_demand_equiv: $11,800  savings: $3,560 (30.2%)
platform  effective_cost: $14,100  on_demand_equiv: $19,300  savings: $5,200 (26.9%)
__untagged__  effective_cost: $2,100  on_demand_equiv: $2,900  savings: $800 (27.6%)

Requires CUR delivery to S3 + Athena. Set CUR_S3_BUCKET, CUR_ATHENA_DATABASE, CUR_ATHENA_TABLE, CUR_ATHENA_RESULTS_BUCKET.


Enterprise SSO (OIDC)

Enterprise plan. Lets your whole team sign in with their company credentials via Okta, Azure AD, Google Workspace, Auth0, or any OIDC-compatible IdP. IdP groups automatically map to nable RBAC roles, with no manual API key distribution needed.

How it works: User clicks "Sign in with SSO" → browser redirects to your IdP → IdP authenticates and returns an ID token → nable validates the token, reads the groups claim, and maps groups to admin / analyst / viewer → user receives a Team license key automatically.
1

Create an OAuth2 app in your IdP. Set the redirect URI to https://getnable.com/api/sso/oidc-callback. Request scopes: openid email profile groups.

2

Enable the groups claim in the ID token. Steps vary by IdP:

  • Okta: Authorization Server → Claims → Add → set Name=groups, Token type=ID, Filter=Matches regex .*
  • Azure AD / Entra ID: App registration → Token configuration → Add groups claim → select "Security groups". Use OIDC_GROUPS_CLAIM=roles and add App Roles in the manifest.
  • Google Workspace: Configure a custom claim via the Admin SDK. Set OIDC_GROUPS_CLAIM to match your claim name.
  • Auth0: Add an Action or Rule to include groups/roles in the ID token.
3

Run the wizard to configure and store credentials:

finops setup sso
4

Add the env vars to your Vercel project (or wherever nable runs). Test by visiting /api/sso/oidc-start.

Role mapping example

OIDC_ISSUER=https://yourcompany.okta.com
OIDC_CLIENT_ID=0oa1abc...
OIDC_CLIENT_SECRET=your-client-secret
OIDC_GROUPS_CLAIM=groups
OIDC_ROLE_MAP={"finops-admins":"admin","engineering":"analyst","finance":"viewer"}
OIDC_DEFAULT_ROLE=viewer  # fallback for users not in any mapped group

RBAC roles

RoleCan do
adminAll queries, set budgets, manage API keys, create tickets, view all teams
analystAll queries and recommendations, cannot manage keys or budgets
viewerRead-only: cost summaries, anomalies, rightsizing. Cannot set budgets or create tickets

All environment variables

Full reference. The wizard sets these for you. Use this table if you're deploying in CI/CD or Docker.

Variable Provider Required
AWS_ACCESS_KEY_IDAWSRequired
AWS_SECRET_ACCESS_KEYAWSRequired
AWS_DEFAULT_REGIONAWSOptional
AZURE_TENANT_IDAzureRequired
AZURE_CLIENT_IDAzureRequired
AZURE_CLIENT_SECRETAzureRequired
AZURE_SUBSCRIPTION_IDAzureRequired
GOOGLE_APPLICATION_CREDENTIALSGCPRequired
GCP_PROJECT_IDGCPRequired
GCP_BIGQUERY_DATASETGCPOptional
DATADOG_API_KEYDatadogRequired
DATADOG_APP_KEYDatadogRequired
DATADOG_SITEDatadogOptional
SNOWFLAKE_ACCOUNTSnowflakeRequired
SNOWFLAKE_USERSnowflakeRequired
SNOWFLAKE_PASSWORDSnowflakeRequired
SNOWFLAKE_WAREHOUSESnowflakeRequired
SNOWFLAKE_CREDIT_PRICESnowflakeOptional
SNOWFLAKE_ROLESnowflakeOptional
GITHUB_TOKENGitHubRequired
LANGFUSE_PUBLIC_KEYLangfuseRequired
LANGFUSE_SECRET_KEYLangfuseRequired
LANGFUSE_HOSTLangfuseOptional
DATABRICKS_HOSTDatabricksRequired
DATABRICKS_TOKENDatabricksRequired
DATABRICKS_ACCOUNT_IDDatabricksOptional
DATABRICKS_DBU_PRICEDatabricksOptional
STRIPE_SECRET_KEYStripeRequired
SLACK_WEBHOOK_URLSlackOptional
TEAMS_WEBHOOK_URLTeamsOptional
FINOPS_DIGEST_TOEmailOptional
JIRA_URLJiraOptional
LINEAR_API_KEYLinearOptional
GITHUB_ISSUES_REPOGitHub IssuesOptional
Slack bot
SLACK_BOT_TOKENSlack botRequired
SLACK_APP_TOKENSlack botRequired
ANTHROPIC_API_KEYSlack botRequired
SLACK_DAILY_CHANNELSlack botOptional
PR cost comments
GITHUB_WEBHOOK_SECRETPR commentsOptional
PR_COST_THRESHOLD_USDPR commentsOptional
PR_WEBHOOK_PORTPR commentsOptional
Idle resource cleanup
FINOPS_CLEANUP_ENABLEDCleanupOptional
FINOPS_PROTECTED_TAGSCleanupOptional
Rate detection (CUR / Athena)
CUR_ATHENA_DATABASERate detectionOptional
CUR_ATHENA_TABLERate detectionOptional
Enterprise SSO (OIDC)
OIDC_ISSUERSSORequired
OIDC_CLIENT_IDSSORequired
OIDC_CLIENT_SECRETSSORequired
OIDC_REDIRECT_URISSOOptional
OIDC_GROUPS_CLAIMSSOOptional
OIDC_ROLE_MAPSSOOptional
OIDC_DEFAULT_ROLESSOOptional
License
FINOPS_LICENSE_KEYYour Team license key. Set this in the env block of your MCP config to unlock Team features.Optional

Troubleshooting

"Cost Explorer must be enabled"

Go to AWS Console → Billing → Cost Explorer → Enable Cost Explorer. Takes up to 24 hours. This is required even if you have an active account.

MCP server not showing in Claude / Cursor

Fully quit and reopen the app after editing the config file. Most clients only read config at startup. Run finops-mcp manually in terminal to confirm there are no Python errors.

Credentials not persisting after restart

Install the keyring extra: pip install finops-mcp[keyring]. Without it, credentials fall back to a local encrypted file. Re-run finops setup after installing.

Snowflake: "Object does not exist"

The user needs IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE granted to their role. Run as ACCOUNTADMIN: GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE TO ROLE your_role;

command not found: finops after pip install

pip installed the package but the executable isn't in your PATH. This is common on macOS when using the system Python or Homebrew.

Fix: find and add the pip bin directory:

# Find where pip puts executables
python3 -m site --user-base
# Add /bin to that path, e.g.:
export PATH="$HOME/Library/Python/3.11/bin:$PATH"
# Add that export line to ~/.zshrc to make it permanent

Or use pipx: pipx install finops-mcp. It handles PATH automatically.

python3: command not found / pip not available

Python 3.9+ is required. Check your version first:

python3 --version

If that fails, install Python from python.org or via Homebrew: brew install python. On Windows, install from the Microsoft Store or python.org. Make sure to check "Add Python to PATH" during setup.

AWS connected but showing no data / zero costs

Three common causes:

  • 1. Cost Explorer not enabled. Go to AWS Console → Billing → Cost Explorer → Enable. Takes up to 24 hours to populate historical data.
  • 2. Wrong AWS profile. Run aws sts get-caller-identity to confirm which account nable is reading from. If it's wrong, re-run finops setup aws and select the correct profile.
  • 3. IAM missing ce:GetCostAndUsage. The IAM user or role needs Cost Explorer read permissions. See the AWS setup section for the exact policy.

Still stuck?

Email us with your finops-doctor output and we'll debug with you.

hello@getnable.com