expense_cost_savings_analysis
Analyze expense data to identify cost reduction opportunities and optimize spending patterns for improved financial efficiency.
Instructions
Identify potential cost savings opportunities
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| lookbackMonths | No |
Implementation Reference
- src/tools/expense-tools.ts:184-208 (registration)Full tool definition and registration as part of expenseTools array, including name, description, input schema, and handler.{ name: "expense_cost_savings_analysis", description: "Identify potential cost savings opportunities", inputSchema: { type: "object", properties: { lookbackMonths: { type: "number", default: 6 } } }, handler: async (args: any): Promise<ToolResult> => { try { const result = await pythonBridge.callPythonFunction({ module: 'expense_tracking', function: 'ExpenseTracker.identify_cost_savings', args: [args.lookbackMonths || 6] }); return result; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) }; } } },
- src/tools/expense-tools.ts:193-207 (handler)The MCP tool handler function that delegates to the Python backend via PythonBridge.handler: async (args: any): Promise<ToolResult> => { try { const result = await pythonBridge.callPythonFunction({ module: 'expense_tracking', function: 'ExpenseTracker.identify_cost_savings', args: [args.lookbackMonths || 6] }); return result; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) }; } }
- src/tools/expense-tools.ts:187-192 (schema)Input schema for the tool defining the lookbackMonths parameter.inputSchema: { type: "object", properties: { lookbackMonths: { type: "number", default: 6 } } },
- Python method containing the core business logic for cost savings analysis, invoked by the TS handler.def identify_cost_savings(self, lookback_months: int = 6) -> List[Dict]: """Identify potential cost savings opportunities""" end_date = date.today() start_date = end_date - timedelta(days=30 * lookback_months) recent_expenses = [ e for e in self.expenses if start_date <= e.date <= end_date ] suggestions = [] # 1. Duplicate vendor analysis vendor_category_spend = {} for expense in recent_expenses: vendor = self.vendors.get(expense.vendor_id) if vendor: key = (expense.category, vendor.vendor_id) if key not in vendor_category_spend: vendor_category_spend[key] = {'vendor': vendor.name, 'total': 0, 'count': 0} vendor_category_spend[key]['total'] += expense.amount vendor_category_spend[key]['count'] += 1 # Find categories with multiple vendors category_vendors = {} for (category, vendor_id), data in vendor_category_spend.items(): if category not in category_vendors: category_vendors[category] = [] category_vendors[category].append(data) for category, vendors in category_vendors.items(): if len(vendors) > 2: total_spend = sum(v['total'] for v in vendors) suggestions.append({ 'type': 'Vendor Consolidation', 'category': category.value, 'description': f"Consider consolidating {len(vendors)} vendors", 'current_spend': round(total_spend, 2), 'potential_savings': round(total_spend * 0.1, 2), # 10% savings estimate 'vendors': [v['vendor'] for v in vendors] }) # 2. Recurring expense optimization recurring_expenses = [e for e in recent_expenses if e.recurring] recurring_by_category = {} for expense in recurring_expenses: if expense.category not in recurring_by_category: recurring_by_category[expense.category] = [] recurring_by_category[expense.category].append(expense) for category, expenses in recurring_by_category.items(): if len(expenses) > 5: total = sum(e.amount for e in expenses) suggestions.append({ 'type': 'Recurring Expense Review', 'category': category.value, 'description': f"Review {len(expenses)} recurring expenses", 'current_spend': round(total, 2), 'potential_savings': round(total * 0.15, 2), # 15% savings estimate 'action': 'Negotiate annual contracts or review necessity' }) # 3. Outlier detection df = pd.DataFrame([{ 'amount': e.amount, 'category': e.category.value, 'vendor': self.vendors.get(e.vendor_id, Vendor("", "Unknown", {})).name } for e in recent_expenses]) if not df.empty: category_stats = df.groupby('category')['amount'].agg(['mean', 'std', 'count']) for expense in recent_expenses: cat_stats = category_stats.loc[expense.category.value] if cat_stats['count'] > 5: # Need enough data z_score = (expense.amount - cat_stats['mean']) / cat_stats['std'] if cat_stats['std'] > 0 else 0 if z_score > 3: # 3 standard deviations vendor = self.vendors.get(expense.vendor_id, Vendor("", "Unknown", {})) suggestions.append({ 'type': 'Unusual Expense', 'category': expense.category.value, 'description': f"Expense significantly above average", 'vendor': vendor.name, 'amount': expense.amount, 'average': round(cat_stats['mean'], 2), 'action': 'Review for accuracy or negotiate' }) return suggestions
- src/index.ts:32-44 (registration)Main tool registry where expenseTools (including expense_cost_savings_analysis) is included in the allTools array used by the MCP server.const allTools = [ ...excelTools, ...financialTools, ...rentalTools, ...expenseTools, ...reportingTools, ...cashFlowTools, ...taxTools, ...analyticsTools, ...chartTools, ...complianceTools, ...propertyTools, ];