list_expenses
Filter and retrieve your expense records by category and date range.
Instructions
List expenses with optional category and date filters.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | ||
| start_date | No | ||
| end_date | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- main.py:200-214 (handler)The `list_expenses` tool handler function, decorated with @mcp.tool. It loads expenses from storage, optionally filters by category/date range, and returns sorted results.
@mcp.tool def list_expenses( category: str | None = None, start_date: str | None = None, end_date: str | None = None, ) -> list[Expense]: """List expenses with optional category and date filters.""" expenses = _load_expenses() filtered = _filter_expenses( expenses, category=category, start_date=start_date, end_date=end_date, ) return sorted(filtered, key=lambda item: (item.expense_date, item.created_at)) - main.py:18-24 (schema)The Expense pydantic model used as the return type of list_expenses.
class Expense(BaseModel): id: str amount: str category: str description: str expense_date: str created_at: str - main.py:200-214 (registration)Registration is implicit via the @mcp.tool decorator on the list_expenses function (line 200), using FastMCP.
@mcp.tool def list_expenses( category: str | None = None, start_date: str | None = None, end_date: str | None = None, ) -> list[Expense]: """List expenses with optional category and date filters.""" expenses = _load_expenses() filtered = _filter_expenses( expenses, category=category, start_date=start_date, end_date=end_date, ) return sorted(filtered, key=lambda item: (item.expense_date, item.created_at)) - main.py:145-171 (helper)The _filter_expenses helper used by list_expenses to apply category and date filters.
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 - main.py:59-69 (helper)The _load_expenses helper used by list_expenses to read expenses from the JSON data file.
def _load_expenses() -> list[Expense]: if not DATA_FILE.exists(): return [] with DATA_FILE.open("r", encoding="utf-8") as file: data = json.load(file) if not isinstance(data, list): raise ValueError("Expense store is invalid. Expected a list of expenses.") return [Expense.model_validate(item) for item in data]