From 4a309cbfb3f7dc5ff7772e794389f4cf63440600 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 25 Dec 2025 04:17:48 +0000 Subject: [PATCH] fix: update get_budgets to match actual monarchmoney API response structure The monarchmoney library's get_budgets() returns budgetData.monthlyAmountsByCategory and categoryGroups, not a simple 'budgets' array. Updated parsing to correctly extract budget data by category with monthly planned/actual/remaining amounts. --- src/monarch_mcp_custom/server.py | 50 +++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/monarch_mcp_custom/server.py b/src/monarch_mcp_custom/server.py index 5948461..9bd0f9d 100644 --- a/src/monarch_mcp_custom/server.py +++ b/src/monarch_mcp_custom/server.py @@ -112,19 +112,53 @@ async def get_budgets(reason: Optional[str] = None) -> str: client = await get_authenticated_client() budgets = await client.get_budgets() + # Build a category lookup from categoryGroups + category_lookup = {} + for group in budgets.get("categoryGroups", []): + for cat in group.get("categories", []): + category_lookup[cat.get("id")] = { + "name": cat.get("name"), + "group": group.get("name"), + "variability": cat.get("budgetVariability"), + } + + # Process monthly amounts by category budget_list = [] - for b in budgets.get("budgets", []): - budget_list.append( + for item in budgets.get("budgetData", {}).get("monthlyAmountsByCategory", []): + cat_id = (item.get("category") or {}).get("id") + cat_info = category_lookup.get(cat_id, {}) + + for monthly in item.get("monthlyAmounts", []): + budget_list.append( + { + "month": monthly.get("month"), + "category": cat_info.get("name"), + "group": cat_info.get("group"), + "planned": monthly.get("plannedCashFlowAmount"), + "actual": monthly.get("actualAmount"), + "remaining": monthly.get("remainingAmount"), + "rollover": monthly.get("previousMonthRolloverAmount"), + } + ) + + # Also include monthly totals summary + totals = [] + for total in budgets.get("budgetData", {}).get("totalsByMonth", []): + totals.append( { - "name": b.get("name"), - "amount": b.get("amount"), - "spent": b.get("spent"), - "remaining": b.get("remaining"), - "category": (b.get("category") or {}).get("name"), + "month": total.get("month"), + "income_planned": (total.get("totalIncome") or {}).get("plannedAmount"), + "income_actual": (total.get("totalIncome") or {}).get("actualAmount"), + "expenses_planned": (total.get("totalExpenses") or {}).get( + "plannedAmount" + ), + "expenses_actual": (total.get("totalExpenses") or {}).get( + "actualAmount" + ), } ) - return serialize_json(budget_list) + return serialize_json({"budgets": budget_list, "totals": totals}) def validate_account_id(account_id: str) -> int: