Azure FinOps MCP Server

io.github.raviteja-pegata由 GitHub 帳號 raviteja-pegata 發布v0.1.1更新於 Nov 3, 2026

Azure FinOps MCP: cost, budgets, forecasting and optimization for Claude, VS Code and Cursor.

已驗證STDIO僅桌面雲端與基礎設施金融

概覽

AI 產生的概覽

在本機執行的 MCP 伺服器,讓助理在允許的訂用帳戶範圍內進行 Azure 成本分析、預算追蹤、支出預測與閒置資源最佳化。

可以做什麼
  • 列出允許存取的訂用帳戶與其易讀名稱
  • 查詢成本總額、本月至今支出,以及依服務、資源群組、位置、計量或標籤的明細,並可跨訂用帳戶彙總
  • 查看單一訂用帳戶或全部訂用帳戶的預算使用情況
  • 找出閒置資源、取得 Azure Advisor 成本建議、檢視虛擬機器 CPU 使用率
  • 預測單一訂用帳戶或整個組合的月底支出
適用情境
適合想用自然語言向助理詢問 Azure 支出、預算餘裕、節省空間或月底預測的情況,尤其是需要跨多個訂用帳戶查看時,不必自行撰寫查詢。
執行需求
以 Python 套件形式在本機執行(需 Python 3.11+),透過 stdio 啟動;需安裝 Azure CLI 並已執行 az login,遠端部署時可使用受控識別。必須設定 AZURE_ALLOWED_SUBSCRIPTIONS 與 AZURE_DEFAULT_SUBSCRIPTION,可選 FINOPS_CACHE_TTL_SECONDS。所用身分需在每個要查詢的訂用帳戶上具備 Cost Management Reader、Reader 與 Monitoring Reader 角色。
安裝前請注意
它會讀取 Azure 租用戶中真實的帳務與資源資料,訂用帳戶允許清單與 RBAC 範圍決定助理能看到什麼,請只對確實需要開放的訂用帳戶授予這三個唯讀角色。Cost Management 有速率限制,頻繁查詢可能被節流。README 中的遠端 HTTP 部署方式預設沒有身分驗證,需自行加上。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Azure FinOps MCP Server,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

Azure FinOps MCP Server

An MCP server that gives LLM clients (Claude Desktop, Claude Code, VS Code, Cursor) conversational access to Azure cost analysis, budget tracking, forecasting, and resource optimization — across multiple subscriptions.

Tools

Discovery

ToolPurpose
list_subscriptionsList allowed subscriptions with friendly names

Cost Analysis

ToolPurpose
get_cost_summaryTotal cost for a date range (single sub)
get_cost_by_dimensionCost breakdown by service / RG / location / meter
get_cost_by_tagCost grouped by tag value (showback/chargeback)
get_month_to_date_costCurrent-month spend (single sub)
get_portfolio_month_to_date_costCurrent-month spend across ALL subs

Budgets

ToolPurpose
get_budget_statusBudget consumption for a single sub
get_portfolio_budget_statusBudget status across ALL subs

Optimization

ToolPurpose
find_idle_resourcesUnattached disks, stranded IPs/NICs, stopped VMs
find_idle_resources_portfolioIdle resources across ALL subs
get_advisor_recommendationsAzure Advisor cost recs with annual savings
get_vm_utilizationCPU stats to validate rightsizing

Forecasting

ToolPurpose
forecast_month_end_spendPredicted month-end cost (single sub)
forecast_portfolio_month_end_spendPredicted month-end cost across ALL subs

Quick Install

bash
pip install azure-finops-mcp

Then add it to your MCP client config using the installed command — no cloning needed:

json
{  "mcpServers": {    "azure-finops": {      "command": "azure-finops-mcp",      "env": {        "AZURE_ALLOWED_SUBSCRIPTIONS": "sub-id-1,sub-id-2",        "AZURE_DEFAULT_SUBSCRIPTION": "sub-id-1"      }    }  }}

See the Client Configuration section below for per-client config file locations.


Prerequisites

  • Python 3.11+
  • Azure CLI installed and logged in (az login)

Azure RBAC Permissions

The identity running this server (your user, a service principal, or a managed identity) needs three roles assigned on each subscription you want to query:

RolePurpose
Cost Management ReaderCost analysis, forecasting, budget queries
ReaderResource inventory via Resource Graph
Monitoring ReaderVM utilization metrics via Azure Monitor

Assign via Azure CLI

bash
SUBSCRIPTION_ID="<your-subscription-id>"PRINCIPAL_ID="<object-id-of-user-sp-or-managed-identity>"
for ROLE in "Cost Management Reader" "Reader" "Monitoring Reader"; do  az role assignment create \    --assignee "$PRINCIPAL_ID" \    --role "$ROLE" \    --scope "/subscriptions/$SUBSCRIPTION_ID"done

Repeat for each subscription listed in AZURE_ALLOWED_SUBSCRIPTIONS.

Local development (your own user)

bash
az loginaz account set --subscription "<your-subscription-id>"
# Check your object IDaz ad signed-in-user show --query id -o tsv

Your user already has these roles if you're a subscription Owner or Contributor. If not, ask your Azure admin to assign them.

Managed Identity (Container Apps deployment)

After deploying with deploy.sh, the script automatically assigns these three roles to the Container App's system-assigned managed identity on each allowed subscription. No credentials or secrets are needed — DefaultAzureCredential picks up the managed identity automatically at runtime.

Install

bash
git clone <your-repo-url> azure-finops-mcpcd azure-finops-mcp
python3 -m venv .venvsource .venv/bin/activate      # Windows: .venv\Scripts\activatepip install -e .
cp .env.example .env# Edit .env: set your subscription IDs

Configure .env

bash
# Required: comma-separated subscription IDs the server may queryAZURE_ALLOWED_SUBSCRIPTIONS=sub-id-1,sub-id-2,sub-id-3
# Required: default subscription (must be in the list above)AZURE_DEFAULT_SUBSCRIPTION=sub-id-1

Test with MCP Inspector

The Inspector is a web UI that lets you call tools interactively and see raw JSON-RPC messages. Always test here before connecting to Claude Desktop.

bash
# Use the venv's python3 explicitly — the Inspector launches a subprocess# and needs the binary that has mcp + azure SDKs installed.npx @modelcontextprotocol/inspector $(which python3) -m azure_finops_mcp.server

In the Inspector UI:

  1. Verify Transport Type is STDIO
  2. Click Connect — should succeed and show "azure-finops" as the server name
  3. Navigate to Tools, click List Tools — you should see all 15 tools
  4. Try list_subscriptions first (no arguments needed)
  5. Try get_month_to_date_cost (no arguments needed — uses default sub)

Client Configuration

Find the absolute path to your venv's Python first — you'll need it in every config below:

bash
# With your venv activated:which python3# e.g. /Users/yourname/azure-finops-mcp/.venv/bin/python3

Claude Desktop

Edit claude_desktop_config.json:

OSPath
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json
json
{  "mcpServers": {    "azure-finops": {      "command": "/absolute/path/to/.venv/bin/python3",      "args": ["-m", "azure_finops_mcp.server"],      "env": {        "AZURE_ALLOWED_SUBSCRIPTIONS": "sub-1,sub-2,sub-3",        "AZURE_DEFAULT_SUBSCRIPTION": "sub-1",        "FINOPS_CACHE_TTL_SECONDS": "900"      }    }  }}

Restart Claude Desktop. A tool icon in the chat input confirms the server connected.


VS Code (GitHub Copilot / Agent mode)

Create .vscode/mcp.json in your workspace (or add to user settings.json under "mcp"):

json
{  "servers": {    "azure-finops": {      "type": "stdio",      "command": "/absolute/path/to/.venv/bin/python3",      "args": ["-m", "azure_finops_mcp.server"],      "env": {        "AZURE_ALLOWED_SUBSCRIPTIONS": "sub-1,sub-2,sub-3",        "AZURE_DEFAULT_SUBSCRIPTION": "sub-1",        "FINOPS_CACHE_TTL_SECONDS": "900"      }    }  }}

Requires VS Code 1.99+ with the GitHub Copilot extension. Open the Chat panel, switch to Agent mode, and the azure-finops tools will appear automatically.


Cursor

Create or edit ~/.cursor/mcp.json:

json
{  "mcpServers": {    "azure-finops": {      "command": "/absolute/path/to/.venv/bin/python3",      "args": ["-m", "azure_finops_mcp.server"],      "env": {        "AZURE_ALLOWED_SUBSCRIPTIONS": "sub-1,sub-2,sub-3",        "AZURE_DEFAULT_SUBSCRIPTION": "sub-1",        "FINOPS_CACHE_TTL_SECONDS": "900"      }    }  }}

Or add it via Cursor Settings → MCP → Add new global MCP server. Restart Cursor. The tools appear in Cursor's Agent/Composer panel.


Claude Code (CLI)

bash
claude mcp add azure-finops \  /absolute/path/to/.venv/bin/python3 \  -m azure_finops_mcp.server \  -e AZURE_ALLOWED_SUBSCRIPTIONS=sub-1,sub-2,sub-3 \  -e AZURE_DEFAULT_SUBSCRIPTION=sub-1

Remote HTTP (after deploying to Azure Container Apps)

All clients support connecting to the deployed server over HTTP — no local Python needed:

Claude Desktop / Cursor — add to the same config files above:

json
{  "mcpServers": {    "azure-finops": {      "type": "http",      "url": "https://<your-container-app-fqdn>/mcp"    }  }}

VS Code — in .vscode/mcp.json:

json
{  "servers": {    "azure-finops": {      "type": "http",      "url": "https://<your-container-app-fqdn>/mcp"    }  }}

Claude Web — Settings → Integrations → Add → https://<your-container-app-fqdn>/mcp

Example Prompts

Try these once connected:

  • "What are our allowed subscriptions?"
  • "What's our total month-to-date spend across all subscriptions?"
  • "Which 10 services cost the most on our prod subscription last month?"
  • "Break down last quarter's spend by the costcenter tag."
  • "Are any budgets close to breaching?"
  • "Show me idle resources across all our subscriptions."
  • "What does Azure Advisor recommend for cost savings?"
  • "Is VM my-analytics-vm actually being used? Check its CPU over 14 days."
  • "Compare our forecast for this month against our budgets."

Architecture

Claude Desktop ◄─┐VS Code        ◄─┤Cursor         ◄─┼──stdio / HTTP──► Azure FinOps MCP Server ◄──REST──► Azure APIsClaude Code    ◄─┤                        │Claude Web     ◄─┘                        ├── config.py          ← env + allowlist                                          ├── azure_clients.py   ← shared credential                                          ├── cache.py           ← TTL cache                                          ├── server.py          ← FastMCP + registration                                          └── tools/                                              ├── subscriptions  ← discovery                                              ├── cost           ← queries + portfolio                                              ├── budgets        ← budget status                                              ├── optimization   ← idle + advisor + metrics                                              └── forecast       ← predictions

Key design decisions

Narrow tools over flexible tools. The LLM picks among well-named tools far better than it constructs complex query objects. 15 purpose-built tools beats 3 configurable ones.

Subscription allowlist. A frozenset loaded from env. Every tool calls resolve_subscription() which refuses any ID not in the list. Prevents the LLM from querying unauthorized subscriptions — important for prompt injection defense.

Portfolio tools catch per-sub errors. When querying 5+ subscriptions, one might have different RBAC or be in a weird state. Portfolio tools (get_portfolio_*) wrap each sub in try/except so partial results are returned with errors listed separately.

Cache on Cost Management only. Cost queries are expensive and rate-limited (~30 req/min per tenant). Cost data updates hourly at best. Default 15-minute TTL trades almost nothing in freshness for significant rate-limit headroom. Resource Graph and Advisor are fast and cheap — no caching needed.

Structured returns, not prose. Tools return dicts with columns/rows/metadata. The LLM narrates them naturally. This avoids encoding English into tool responses (which makes them brittle to prompt changes).

Deploying to Azure (Remote Mode)

For team-wide access, deploy as a remote HTTP server:

  1. Transport swap in server.py:

    python
    mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
  2. Dockerfile:

    dockerfile
    FROM python:3.12-slimWORKDIR /appCOPY . .RUN pip install --no-cache-dir -e .CMD ["azure-finops-mcp"]
  3. Deploy to Azure Container Apps with a user-assigned managed identity.

  4. Grant RBAC to the managed identity (same 3 roles: Cost Management Reader, Reader, Monitoring Reader) on each subscription.

  5. Add auth via APIM or Azure Front Door + Entra ID. MCP supports OAuth for remote servers.

  6. DefaultAzureCredential picks up the managed identity automatically — no code changes needed.

Troubleshooting

ProblemFix
DefaultAzureCredential auth errorsRun az login and verify with az account show
429 throttling on Cost ManagementIncrease FINOPS_CACHE_TTL_SECONDS
Empty budget listBudgets must exist in the portal — the API doesn't create them
find_idle_resources errorsYou need Reader RBAC at subscription scope
Inspector "Connection Error"Use absolute path to venv's python3 in Command field
print() breaks the serverNever use print() in MCP tools — it corrupts the stdio JSON stream. Use logging instead

來源:README.md,提交 ef5b83b

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.1.1最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分