An MCP server for managing group expenses with support for equal, percentage-based, and weighted expense splitting
The server has 6 well-intentioned tools with mostly clear verb-noun naming (create_group, list_groups, add_people, get_group_info, add_expense, save_report). Tool descriptions are present and adequate (10-150 chars), meeting the minimum bar. However, significant gaps emerge in parameter descriptions, schema completeness, and error handling. The add_expense tool has a sophisticated JSON Schema with conditional validation (allOf, if/then), but 4 of 6 tools lack explicit input schemas in the visible code, relying on SDK inference. Parameter descriptions vary in completeness, many are terse (e.g., 'names of the people' for add_people) and lack actionable guidance. Error handling is minimal: no recovery guidance, no categorization of retryable vs fatal errors, and no structured error responses. The code includes basic logging (tool_logging.go) but no per-request _meta.logLevel or structured error returns. Security checks are absent: no rate limiting, no permission gates, and no audit trail. Overall, this is a solid C+ that could reach B with parameter description improvements and formal error handling.
Add expense to the group paid by a person. This tool is thread-safe and supports concurrent expense submissions - multiple expenses can be added in parallel for better performance.
Add people to the group
Create a group
Get group info or details
List groups
Save a markdown report to disk under reports/ with a unique id
Missing or incomplete input schemas for 4 of 6 tools. list_groups, add_people, create_group, and get_group_info do not show explicit schema definitions in main.go, they rely on SDK inference from handler signatures, violating the pattern that every tool must have a formally registered schema.
Parameter descriptions are minimal and lack actionable guidance. 'names of the people' (add_people) and 'group name to which the person will be added to' (add_people) do not explain formats, dependencies, or constraints. Descriptions should state: what format is expected, what happens if the parameter is invalid, and any prerequisites (e.g., 'People must already exist in the group' for add_people).
No error recovery guidance. The code calls sendExpenseElicitRequest() on missing parameters (expense.go line ~65), but the pattern returns plain error strings. Error responses must tell the LLM what to do next: 'Group not found. Call list_groups() to see available groups' or 'Person not in group. Call add_people() first.' Currently, errors are silent or non-informative.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 59 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 44 | - | v1 |
No error classification. Tools do not distinguish between retryable errors (network timeout), user-fixable errors (missing group), and fatal errors (invalid schema). LLMs cannot plan recovery without this classification.
Destructive operations (create_group, add_expense, save_report) lack confirmation or dry-run support. If an LLM calls create_group with a typo in the name, or add_expense with the wrong amount, there is no way to confirm before execution or undo afterwards.
No documentation of output schemas. While add_expense and save_report include response structs (AddExpenseOutput, etc.), the tool registration in main.go does not formally declare output types. LLMs cannot plan downstream tool calls without knowing what fields to expect in responses.
No rate limiting, permission checks, or audit trail. The server accepts any HTTP request without verifying the caller, limiting concurrent calls, or logging who called what. For a financial tool (expense splitter), this is a security gap: agents can invoke unlimited add_expense calls or manipulate group state without consent.