Local AI expense-tracking agent built with LangChain, FastMCP, and DeepSeek. Provides tools for managing expenses, budgets, and financial summaries via MCP protocol.
SpendWise has 7 tools with clear verb-noun naming (add_, update_, delete_, list_, summarize, check_, set_). All tools have descriptions (avg 65 chars, baseline 194). Input schemas are present with types and descriptions. However, output schemas are undocumented, responses are free-text strings rather than structured JSON. Error handling is basic (string messages, no recovery guidance). Parameters lack enums for constrained values (e.g., group_by in summarize, category filtering). No tool annotations (readOnlyHint, destructiveHint). Missing pagination details for list_expenses despite accepting limit. Descriptions are functional but brief, lacking WHEN/WHY context for LLM selection.
Add a new expense to the database.
Check budget status for a specific category or all categories.
Delete an expense from the database by ID.
List and filter recorded expenses.
Set or update a monthly budget limit for a category.
Summarize expenses by category, subcategory, or month.
Update an existing expense in the database.
Output schemas undocumented. All tools return free-text strings (e.g., 'Success: Expense added with ID 123...') instead of structured JSON. LLMs cannot reliably extract IDs, counts, or nested data for downstream tool chaining.
Missing enum constraints for categorical parameters. 'group_by' in summarize accepts 'category', 'subcategory', 'month' but is typed as free-form string. LLMs may hallucinate invalid values like 'week' or 'year'. Same issue for category/subcategory filtering across multiple tools.
No tool annotations. delete_expense and update_expense lack destructiveHint/idempotentHint. list_expenses, summarize, check_budget lack readOnlyHint. Clients cannot determine which tools are safe to retry or have side effects.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | <=2025-11-25 | v2 |
Error handling lacks recovery guidance. Errors return plain strings ('Error: Amount must be greater than zero.') without actionable next steps. No distinction between retryable vs user-fixable errors. LLMs cannot self-correct.
Pagination incomplete. list_expenses accepts 'limit' but no offset/cursor or total_count in response. Returning 50 expenses as a flat string makes it impossible for LLMs to know if more results exist or how to fetch them.