get_expense_summary
Retrieve totals and category breakdown for expenses matching specified date range and category filters.
Instructions
Return totals and category breakdown for matching expenses.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | ||
| start_date | No | ||
| end_date | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | Yes | ||
| total_amount | Yes | ||
| category_breakdown | Yes | ||
| filters | Yes |
Implementation Reference
- main.py:217-254 (handler)Handler function for the get_expense_summary tool. It lists expenses (optionally filtered by category/date range), computes total and per-category amounts, and returns an ExpenseSummary Pydantic model with count, total_amount, category_breakdown, and applied filters.
@mcp.tool def get_expense_summary( category: str | None = None, start_date: str | None = None, end_date: str | None = None, ) -> ExpenseSummary: """Return totals and category breakdown for matching expenses.""" filtered = list_expenses( category=category, start_date=start_date, end_date=end_date, ) total = Decimal("0.00") by_category: dict[str, Decimal] = {} for expense in filtered: amount = Decimal(expense.amount) total += amount by_category.setdefault(expense.category, Decimal("0.00")) by_category[expense.category] += amount return ExpenseSummary( count=len(filtered), total_amount=format(total.quantize(Decimal("0.01")), ".2f"), category_breakdown={ category_name: format( category_total.quantize(Decimal("0.01")), ".2f", ) for category_name, category_total in sorted(by_category.items()) }, filters=SummaryFilters( category=category, start_date=start_date, end_date=end_date, ), ) - main.py:33-37 (schema)Pydantic model defining the return schema for get_expense_summary: count (int), total_amount (str), category_breakdown (dict of category to amount string), and filters (SummaryFilters).
class ExpenseSummary(BaseModel): count: int total_amount: str category_breakdown: dict[str, str] filters: SummaryFilters - main.py:27-30 (schema)Pydantic model for the filters sub-object used in ExpenseSummary, capturing the optional category, start_date, and end_date applied to the query.
class SummaryFilters(BaseModel): category: str | None = None start_date: str | None = None end_date: str | None = None - main.py:217-217 (registration)The @mcp.tool decorator registers get_expense_summary as an MCP tool on the FastMCP instance.
@mcp.tool - main.py:145-171 (helper)Helper used by get_expense_summary (via list_expenses) to filter expenses by category and date range.
def _filter_expenses( expenses: list[Expense], category: str | None = None, start_date: str | None = None, end_date: str | None = None, ) -> list[Expense]: normalized_category = category.strip().lower() if category else None parsed_start = date.fromisoformat(start_date) if start_date else None parsed_end = date.fromisoformat(end_date) if end_date else None if parsed_start and parsed_end and parsed_start > parsed_end: raise ValueError("start_date cannot be after end_date.") filtered: list[Expense] = [] for expense in expenses: expense_day = date.fromisoformat(expense.expense_date) if normalized_category and expense.category.lower() != normalized_category: continue if parsed_start and expense_day < parsed_start: continue if parsed_end and expense_day > parsed_end: continue filtered.append(expense) return filtered