Premium crypto tax calculation MCP server & REST API — FIFO, LIFO, Average Cost basis with short/long-term capital gains
Four tools with complete input schemas and descriptions, but significant gaps in parameter documentation and output schema clarity. Tool names follow verb_noun convention (calculate_, parse_, list_, annual_). Descriptions are adequate (100-200 chars) but lack actionable guidance on when to use each tool vs. alternatives. Parameter descriptions exist but are minimal, e.g., 'Trade type' for the 'type' enum lacks context on what buy/sell means in tax context. Output schemas are not documented; LLMs cannot predict response structure. Error handling is basic (generic error messages). No tool annotations (readOnlyHint, idempotentHint). Security is acceptable (no secrets in params, read-only operations), but composition could be tighter, parse_csv_trades and calculate_crypto_tax overlap significantly.
Generate annual tax summary comparing all cost basis methods side by side. Recommends the lowest-tax method.
Calculate capital gains/losses from crypto trades using FIFO, LIFO, or Average Cost basis. Returns per-disposal breakdown with short-term/long-term classification and totals.
List all supported cost basis calculation methods with descriptions.
Parse CSV trade history text and calculate crypto taxes. CSV columns: type, currency, amount, price_per_unit, date, fee (optional).
Output schemas not documented. LLMs cannot predict response structure (e.g., what fields does calculate_crypto_tax return? Is it per-disposal breakdown or aggregated totals?). Responses are JSON-stringified text blocks, not structured objects.
Parameter descriptions are minimal and lack context. 'Trade type' does not explain what buy/sell means in tax calculation. 'CSV text with header row' does not specify required columns or format. LLMs cannot infer constraints from names alone.
Tool composition overlap: parse_csv_trades and calculate_crypto_tax both accept trades and method parameters. The distinction is unclear, does parse_csv_trades always parse first, or can it skip parsing if trades are already structured? This forces LLMs to reason about which tool to call.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2026-07-28+ | v2 |
Error handling is generic. executeTool() catches errors and returns 'Error: {message}' with isError=true, but does not guide recovery. If CSV parsing fails, the LLM receives no hint on how to fix the input or which tool to try next.
No tool annotations. Tools lack readOnlyHint (all are read-only), idempotentHint (all are idempotent), or destructiveHint. Clients cannot infer safety properties without explicit hints.