github Python analyzed eeb287b

getnable/finopsmcp

v0.8.216
github

The headless FinOps intelligence layer: API-first, agent-first cost control for cloud + AI. Connect your cloud stack in Claude, Cursor, or the terminal, and gate what agents do to your infra before they act. Propose-only. Open source, local-first.

maintainer
getnable
licence
Apache-2.0
first seen
2026-07-14
last seen
2026-09-04
releases · 30d
10
short id

Drift inferred · capture-to-capture

  1. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  2. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  3. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  4. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  5. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  6. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  7. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  8. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  9. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  10. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  11. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  12. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  13. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  14. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  15. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  16. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  17. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  18. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  19. HIGH code analysis flagged dynamic code execution in getnable/finopsmcp
  20. HIGH code analysis flagged dynamic code execution ×4 in getnable/finopsmcp
capabilities 10 tools
transport stdio · http counts 10 tools · 0 res · 0 prompts permission surface via code analysis

tools

  • dismiss_recommendation
  • forget_cost_context
  • get_learned_cost_context
  • get_recommendation_learning
  • get_recommendation_quality
  • get_savings_ledger
  • mark_recommendation_acted_on
  • remember_cost_context
  • suggest_cost_policies
  • verify_savings
skills & danger signals github-tarball
prompt-surface shipped agent-instruction files + hidden-content / dangerous-code findings — quoted from the analyzed source

analyzed commit eeb287b · analyzer v33 · 1d ago

danger signals14

code evidence vv0.8.216 · github-tarball
evidence-backed findings quoted directly from the published source artifact — not inferred

code files: 520

filesystem 117

  • fs getnable-finopsmcp-eeb287b/.github/actions/budget-check/entrypoint.py :12 from pathlib import Path
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/agent-cost-ab.py :55 with open(sys.argv[1]) as f:
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/fix_docstrings.py :177 src = open(SERVER).read()
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/gen_tool_docs.py :20 from pathlib import Path
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/generate_sbom.py :18 from pathlib import Path
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/launch_funnel.py :22 from pathlib import Path
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/publish_cfn.py :28 import pathlib
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/redact_screenshots.py :28 from pathlib import Path
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/render_ph_assets.py :22 from pathlib import Path
  • fs (weak) getnable-finopsmcp-eeb287b/scripts/weekly-read.py :29 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/shim/nable_shim.py :28 import shutil
  • fs getnable-finopsmcp-eeb287b/src/finops/accounts.py :16 from pathlib import Path
show 28 more
  • fs getnable-finopsmcp-eeb287b/src/finops/ai_budget.py :30 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/ambient.py :243 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/analytics/benchmarks.py :168 with open(salt_path) as f:
  • fs getnable-finopsmcp-eeb287b/src/finops/analytics/llm_commitments.py :49 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/attribution/mapper.py :27 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/audit/logger.py :19 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/briefing/run.py :29 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/budget/enforcer.py :47 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/cache.py :172 with open(path, "rb") as fh:
  • fs getnable-finopsmcp-eeb287b/src/finops/cleanup/actions.py :31 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/cli_brief.py :17 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/connectors/gcp.py :7 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/connectors/invoice/parser.py :139 with pdfplumber.open(io.BytesIO(data)) as pdf:
  • fs getnable-finopsmcp-eeb287b/src/finops/connectors/saas/snowflake.py :58 with open(self._private_key_path, "rb") as f:
  • fs getnable-finopsmcp-eeb287b/src/finops/connectors/terraform.py :41 with open(state_path) as f:
  • fs getnable-finopsmcp-eeb287b/src/finops/connectors/terraform_estimate.py :30 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/doctor.py :25 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/guard.py :27 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/install_health.py :96 with open(os.path.join(sys.prefix, "pyvenv.cfg"), encoding="utf-8") as fh:
  • fs getnable-finopsmcp-eeb287b/src/finops/license.py :42 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/persona.py :10 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/pr_comments/github_app.py :88 with open(key_path) as f:
  • fs getnable-finopsmcp-eeb287b/src/finops/remediation/gate.py :49 with open(path) as f:
  • fs getnable-finopsmcp-eeb287b/src/finops/remediation/rightsizing_pr.py :27 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/reporting/dashboard.py :20 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/reporting/exporter.py :18 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/scheduler/jobs.py :576 from pathlib import Path
  • fs getnable-finopsmcp-eeb287b/src/finops/security/oauth/aws.py :68 webbrowser.open(url)

77 more not shown — this panel samples each group; the count above is the real total.

shell / exec 24

  • shell (weak) getnable-finopsmcp-eeb287b/scripts/launch_funnel.py :166 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/scripts/weekly-read.py :27 import subprocess
  • shell getnable-finopsmcp-eeb287b/shim/nable_shim.py :29 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/connectors/terraform.py :16 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/connectors/terraform_estimate.py :26 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/remediation/rightsizing_pr.py :26 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/setup_wizard.py :887 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/tagging/tf_state.py :25 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/tools/attribution.py :796 import subprocess as _sp
  • shell getnable-finopsmcp-eeb287b/src/finops/tools/notifications.py :174 import subprocess
  • shell getnable-finopsmcp-eeb287b/src/finops/tools/tickets.py :92 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_audit_spend_safety.py :57 import subprocess
show 12 more
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_audit_tool_surface.py :357 subprocess.run(timeout=300) SIGKILLs terraform when the deadline fires, so
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_cli_e2e.py :15 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_cli_help.py :10 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_entry.py :104 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_mcp_stdio_smoke.py :21 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_no_stale_org_references.py :24 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_onboarding_friction.py :35 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_onboarding_no_creds.py :25 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_one_license_everywhere.py :147 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_shim_floor.py :25 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_shim_reexec.py :30 import subprocess
  • shell (weak) getnable-finopsmcp-eeb287b/tests/test_welcome_activation.py :18 import subprocess

network 48

  • net getnable-finopsmcp-eeb287b/.github/actions/cost-check/entrypoint.py :11 import httpx
  • net (weak) getnable-finopsmcp-eeb287b/scripts/demo_all_normalized.py :60 import httpx # noqa: E402
  • net (weak) getnable-finopsmcp-eeb287b/scripts/launch_funnel.py :21 import urllib.request
  • net getnable-finopsmcp-eeb287b/src/finops/ambient.py :200 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/analytics/benchmarks.py :269 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/azure_detail.py :69 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/azure_optimize.py :71 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/databricks.py :25 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/github_contributions.py :31 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/opencost.py :69 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/anthropic_usage.py :79 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/cloudflare.py :26 import httpx
show 28 more
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/datadog.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/gpu_infra.py :124 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/langfuse.py :23 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/litellm.py :99 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/mongodb_atlas.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/n8n.py :22 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/new_relic.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/notion.py :19 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/openai_usage.py :72 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/openrouter.py :79 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/stripe.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/twilio.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/connectors/saas/vercel.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/doctor.py :282 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/integrations/ticketing.py :25 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/notifications/reports.py :406 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/notifications/slack.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/notifications/teams.py :7 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/pr_comments/github_app.py :98 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/pr_comments/webhook.py :24 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/security/iam_setup.py :513 from urllib.parse import quote
  • net getnable-finopsmcp-eeb287b/src/finops/setup/cloud_infra.py :34 import urllib.parse
  • net getnable-finopsmcp-eeb287b/src/finops/setup_wizard.py :1887 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/telemetry.py :489 import httpx
  • net getnable-finopsmcp-eeb287b/src/finops/update_check.py :44 import httpx
  • net (weak) getnable-finopsmcp-eeb287b/tests/connectors/test_cloudflare_billable_usage.py :15 import httpx
  • net (weak) getnable-finopsmcp-eeb287b/tests/connectors/test_n8n.py :53 with patch("finops.connectors.saas.n8n.httpx.AsyncClient", return_value=mock_client):
  • net (weak) getnable-finopsmcp-eeb287b/tests/connectors/test_stripe_business_snapshot.py :140 "src.finops.connectors.saas.stripe.httpx.AsyncClient",

8 more not shown — this panel samples each group; the count above is the real total.

secrets 36

  • secrets getnable-finopsmcp-eeb287b/.github/actions/cost-check/entrypoint.py :15 GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "")
  • secrets (weak) getnable-finopsmcp-eeb287b/scripts/weekly-read.py :55 POSTHOG_API_KEY = os.environ.get("POSTHOG_PERSONAL_API_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/ambient.py :280 source = "env" if os.getenv("GOOGLE_APPLICATION_CREDENTIALS") else "adc"
  • secrets getnable-finopsmcp-eeb287b/src/finops/attribution/fetcher.py :107 client_secret=os.environ["AZURE_CLIENT_SECRET"],
  • secrets getnable-finopsmcp-eeb287b/src/finops/audit/logger.py :67 raw = os.environ.get("FINOPS_API_KEY", "").strip()
  • secrets getnable-finopsmcp-eeb287b/src/finops/auth/rbac.py :350 raw = os.environ.get("FINOPS_API_KEY", "").strip()
  • secrets getnable-finopsmcp-eeb287b/src/finops/briefing/run.py :161 send = slack.send_bot if os.getenv("SLACK_BOT_TOKEN") else slack.send_webhook
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/azure.py :64 client_secret=os.environ["AZURE_CLIENT_SECRET"],
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/databricks.py :137 self._token = os.getenv("DATABRICKS_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/gcp.py :40 os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/github_contributions.py :268 token = os.getenv("GITHUB_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/invoice/parser.py :310 password = os.environ.get("FINOPS_INVOICE_IMAP_PASSWORD", "")
show 24 more
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/cloudflare.py :145 self._api_token = os.getenv("CLOUDFLARE_API_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/datadog.py :17 self._api_key = os.getenv("DATADOG_API_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/langfuse.py :33 self._secret_key = os.getenv("LANGFUSE_SECRET_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/mongodb_atlas.py :18 self._private_key = os.getenv("MONGODB_ATLAS_PRIVATE_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/new_relic.py :24 self._api_key = os.getenv("NEW_RELIC_API_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/notion.py :35 self._api_key = os.getenv("NOTION_API_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/snowflake.py :30 self._password = os.getenv("SNOWFLAKE_PASSWORD", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/stripe.py :52 self._secret_key = os.getenv("STRIPE_SECRET_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/twilio.py :18 self._auth_token = os.getenv("TWILIO_AUTH_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/connectors/saas/vercel.py :22 self._token = os.getenv("VERCEL_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/demo_data.py :37 os.environ.get("FINOPS_CONTROL_PLANE_SECRET", "").strip()
  • secrets getnable-finopsmcp-eeb287b/src/finops/doctor.py :96 if os.environ.get("FINOPS_VAULT_KEY"):
  • secrets getnable-finopsmcp-eeb287b/src/finops/license.py :46 _env_secret = os.environ.get("FINOPS_LICENSE_SECRET", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/notifications/slack.py :18 return os.environ.get("SLACK_BOT_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/pr_comments/github_app.py :82 key_data = os.environ.get("GITHUB_APP_PRIVATE_KEY", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/pr_comments/webhook.py :31 GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", "")
  • secrets getnable-finopsmcp-eeb287b/src/finops/recommendations/critique.py :366 return bool(os.getenv("ANTHROPIC_API_KEY", "").strip())
  • secrets getnable-finopsmcp-eeb287b/src/finops/security/oauth/gcp.py :91 os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = str(path)
  • secrets getnable-finopsmcp-eeb287b/src/finops/security/vault.py :12 import getpass
  • secrets getnable-finopsmcp-eeb287b/src/finops/setup_scan.py :268 os.environ.get("GOOGLE_APPLICATION_CREDENTIALS") or gcloud_adc_path()
  • secrets getnable-finopsmcp-eeb287b/src/finops/setup_wizard.py :25 import getpass
  • secrets getnable-finopsmcp-eeb287b/src/finops/telemetry.py :51 _POSTHOG_KEY = os.environ.get("NABLE_POSTHOG_KEY", "phc_zcaQqoAXrSghjtbE6VB83p4RjfmcpqezKWV9GdZy4dPv")
  • secrets getnable-finopsmcp-eeb287b/src/finops/tools/notifications.py :53 "method": "webhook" if _srv.os.environ.get("SLACK_WEBHOOK_URL") else "bot_token" if _srv.os.environ.get("SLACK_BOT_TOKEN") else "none",
  • secrets getnable-finopsmcp-eeb287b/src/finops/welcome.py :506 if os.environ.get("OPENAI_API_KEY") or os.environ.get("OPENAI_ADMIN_KEY"):

database 43

  • db getnable-finopsmcp-eeb287b/src/finops/analytics/benchmarks.py :190 from sqlalchemy import text as sql_text
  • db getnable-finopsmcp-eeb287b/src/finops/anomaly/backfill.py :29 from sqlalchemy import distinct, func, select
  • db getnable-finopsmcp-eeb287b/src/finops/anomaly/detector.py :9 from sqlalchemy import and_, distinct, func, select
  • db getnable-finopsmcp-eeb287b/src/finops/auth/rbac.py :271 from sqlalchemy import insert
  • db getnable-finopsmcp-eeb287b/src/finops/budget/enforcer.py :66 from sqlalchemy import insert
  • db getnable-finopsmcp-eeb287b/src/finops/cache.py :33 import sqlite3
  • db getnable-finopsmcp-eeb287b/src/finops/connectors/aws_org.py :146 from sqlalchemy import select, update, insert
  • db getnable-finopsmcp-eeb287b/src/finops/connectors/business_metrics.py :63 from sqlalchemy import select, delete
  • db getnable-finopsmcp-eeb287b/src/finops/connectors/kubernetes_costs.py :506 from sqlalchemy import delete as sql_delete
  • db getnable-finopsmcp-eeb287b/src/finops/doctor.py :474 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/ml/forecasting.py :188 from sqlalchemy import text
  • db getnable-finopsmcp-eeb287b/src/finops/notifications/reports.py :40 from sqlalchemy import func, select
show 28 more
  • db getnable-finopsmcp-eeb287b/src/finops/recommendations/context_memory.py :27 from sqlalchemy import select, update
  • db getnable-finopsmcp-eeb287b/src/finops/recommendations/learning/ledger.py :32 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/recommendations/learning/policy_inference.py :20 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/recommendations/learning/signal.py :30 from sqlalchemy import func, select
  • db getnable-finopsmcp-eeb287b/src/finops/recommendations/savings_tracker.py :28 from sqlalchemy import case, func, select, update
  • db getnable-finopsmcp-eeb287b/src/finops/remediation/rightsizing_pr.py :30 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/scheduler/jobs.py :200 from sqlalchemy import select, and_
  • db getnable-finopsmcp-eeb287b/src/finops/scoring/scorecard.py :529 from sqlalchemy import select, and_, func
  • db getnable-finopsmcp-eeb287b/src/finops/security/vault.py :170 import sqlite3
  • db getnable-finopsmcp-eeb287b/src/finops/server.py :1029 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/slice/dashboards.py :29 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/slice/views.py :16 from sqlalchemy import delete, func, select, update
  • db getnable-finopsmcp-eeb287b/src/finops/storage/category_rollup.py :17 from sqlalchemy import and_, func, select
  • db getnable-finopsmcp-eeb287b/src/finops/storage/db.py :20 from sqlalchemy import (
  • db getnable-finopsmcp-eeb287b/src/finops/storage/snapshots.py :6 from sqlalchemy import and_, select
  • db getnable-finopsmcp-eeb287b/src/finops/tools/attribution.py :224 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/tools/aws_waste.py :1141 from sqlalchemy import text as sql_text
  • db getnable-finopsmcp-eeb287b/src/finops/tools/cost_queries.py :2049 from sqlalchemy import select
  • db getnable-finopsmcp-eeb287b/src/finops/tools/kubernetes.py :685 from sqlalchemy import select, func
  • db getnable-finopsmcp-eeb287b/src/finops/tools/meta.py :174 from sqlalchemy import select, func, text as sql_text
  • db getnable-finopsmcp-eeb287b/src/finops/tools/notifications.py :262 from sqlalchemy import select, func
  • db getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :360 from sqlalchemy import select
  • db (weak) getnable-finopsmcp-eeb287b/tests/test_audit_concurrency.py :411 from sqlalchemy import select
  • db (weak) getnable-finopsmcp-eeb287b/tests/test_audit_storage.py :41 import sqlalchemy as sa
  • db (weak) getnable-finopsmcp-eeb287b/tests/test_cache_hmac.py :8 import sqlite3
  • db (weak) getnable-finopsmcp-eeb287b/tests/test_db_migrations.py :20 import sqlalchemy as sa
  • db (weak) getnable-finopsmcp-eeb287b/tests/test_interactive_smoke.py :136 import sqlite3
  • db (weak) getnable-finopsmcp-eeb287b/tests/test_no_string_bound_to_datetime.py :41 from sqlalchemy import DateTime

3 more not shown — this panel samples each group; the count above is the real total.

tool registrations 10

  • mark_recommendation_acted_on getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :17
  • dismiss_recommendation getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :47
  • suggest_cost_policies getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :142
  • remember_cost_context getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :179
  • get_learned_cost_context getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :237
  • forget_cost_context getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :265
  • verify_savings getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :284
  • get_savings_ledger getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :336
  • get_recommendation_quality getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :430
  • get_recommendation_learning getnable-finopsmcp-eeb287b/src/finops/tools/recommendations.py :454

declared dependencies 30

  • mcp@>=1.28.1,<2
  • not@found
  • boto3@>=1.34.0
  • sqlalchemy@>=2.0.0
  • apscheduler@>=3.10.0
  • cryptography@>=48.0.1
  • keyring@>=25.0.0
  • python-dotenv@>=1.0.0
  • httpx@>=0.27.0
  • pydantic@>=2.0.0
  • pyyaml@>=6.0.0
  • anthropic@>=0.25.0
show 18 more
  • snowflake-connector-python@>=3.6.0
  • msal@>=1.28.0
  • azure-mgmt-costmanagement@>=4.0.0
  • azure-identity@>=1.15.0
  • pyasn1@>=0.6.4
  • google-cloud-billing@>=1.13.0
  • google-cloud-bigquery@>=3.17.0
  • google-cloud-compute@>=1.19.0
  • google-cloud-monitoring@>=2.21.0
  • google-cloud-recommender@>=2.15.0
  • pdfplumber@>=0.10.0
  • pillow@>=12.3.0
  • kubernetes@>=29.0.0
  • psycopg2-binary@>=2.9.0
  • croniter@>=2.0.0
  • pytest@>=8.0
  • pytest-asyncio@>=0.23
  • ruff@>=0.4

transport_posture 1

  • binds all interfaces (0.0.0.0) getnable-finopsmcp-eeb287b/tests/test_audit_tool_surface.py :599 the user wants sharing passes host="0.0.0.0" and gets LAN-wide plain-HTTP