A FastAPI-based banking server with MCP integration for account and transaction management
This MCP server exhibits serious definition quality issues across all dimensions. While tools are named with clear verbs (create_account, deposit, withdraw, balance, transactions), descriptions are minimal and lack actionable context. Parameter descriptions are single-phrase and generic. Most critically, input schemas lack critical details: no enums for constrained values, no numeric bounds (amount could be negative or infinite), no explanation of dependencies. Output schemas are not documented at all, LLMs cannot know what fields to expect from balance or transactions responses. Error handling is minimal with no guidance for recovery. The server operates in HTTP transport but has zero MCP protocol features (no prompts, resources, logging, sampling, elicitation, roots, cancellation, progress, errorReporting, or toolAnnotations). No evidence of tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite clear read/write risk classifications. This is a basic REST API wrapper, not a production-grade MCP server.
Get the balance of an account
Create a new banking account
Deposit money into an account
Get all transactions for an account
Withdraw money from an account
No output schemas documented. LLMs cannot predict response structure for balance (returns {"balance": <number>}?) or transactions (returns array of what fields?). This breaks downstream tool chaining and forces LLMs to guess.
Numeric parameters (amount in deposit/withdraw, account_id across all tools) lack bounds, validation rules, or constraints. LLMs can pass negative amounts, zero, or absurd values like 1e10. No enum for account_id type or constraints.
Tool descriptions are single sentences and lack WHEN/WHY context. 'Create a new banking account' tells LLMs WHAT but not WHEN to use it vs another tool, what it returns, or what happens next. Descriptions should be 10-200 chars and explain preconditions, consequences, and return structure.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 38 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 27 | - | v1 |
No distinction between read and write operations in schema. Tools marked with Risk: WRITE (deposit, withdraw, create_account) should declare destructiveHint: true and idempotentHint: false in tool annotations. balance and transactions should declare readOnlyHint: true. These annotations are MISSING.
Parameter descriptions are generic single-phrase placeholders. 'The ID of the account to deposit into' and 'The amount to deposit' lack detail. No mention of format (integer >= 1 for account_id?), minimum/maximum for amount, or currency. Descriptions should disambiguate the intent and constraints so LLMs self-validate.
Error handling is minimal. withdraw() raises a generic Exception for insufficient funds, which FastAPI converts to HTTP 400 + stack trace. LLMs receive no recovery guidance ('Try checking balance first'). No categorization of errors as retryable, user-fixable, or fatal.
No pagination or result limiting. transactions() returns all transactions for an account with no limit. A large account could return thousands of records, overwhelming context windows. Should accept page/limit parameters and document max result size.
Responses are not structured for agent chaining. create_account returns a full account object, but does not guarantee which fields (id, name, balance) are included. balance returns {balance: ...} with no account_id reference, forcing redundant state tracking. deposit/withdraw return full account but no transaction_id for follow-up queries.