MCP server for managing bank accounts and money transfers using MongoDB for persistence and Temporal for workflow orchestration
The server implements 8 banking tools with basic but incomplete definition quality. All tools have descriptions (20-100 chars) and input schemas are visible in the source code. However, descriptions are generic and lack LLM-optimization (most fall below 50 chars), parameters lack constraints (no enums, min/max bounds), and output schemas are undocumented. Error handling is minimal, tools return generic error dicts without recovery guidance. The naming is clear and verb-focused (create_, delete_, get_, list_, deposit, withdraw, transfer, health_check), but lacks the richness needed for production LLM agents. No tool annotations (readOnlyHint, destructiveHint) are present despite clear risk classifications (READ_ONLY, WRITE, DESTRUCTIVE). Parameter descriptions exist but are minimal and lack format/constraint detail. This is typical C-grade community work: functional definitions but missing patterns that guide LLM behavior.
Create a new account with the given username and initial balance
Delete the account with the given username
Deposit money into the specified account
Get account information for the given username
Check the health of the MCP server
List all accounts in the system
Transfer money from one account to another
Descriptions are too generic and under 50 characters for most tools. 'Check the health of the MCP server' (35 chars) and 'Delete the account with the given username' (42 chars) lack context for LLM selection. LLMs need: WHAT it does, WHEN to use it, and prerequisites.
No parameter constraints (min/max for amounts, enum values for statuses). deposit/withdraw accept 'amount' as unbounded float, LLM could pass 999999999 or negative values. No validation guidance in descriptions.
Output schemas are undocumented. Tools return dict/list but LLMs don't know field names, types, or structure. E.g., create_account returns {'success': bool, 'data': {...}, 'error': str}, this structure is invisible in tool definition.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 47 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 41 | - | v1 |
Withdraw money from the specified account
Error handling is minimal and non-actionable. Tools catch exceptions and return {'error': 'Workflow execution failed: <msg>'}, no recovery guidance, no classification (retryable vs fatal), no suggestion for next steps. LLM has nothing to act on.
No tool annotations despite clear risk classifications in metadata (WRITE, DESTRUCTIVE, READ_ONLY). Tools like delete_account should carry destructiveHint=true; deposit/withdraw should carry idempotentHint info. Annotations guide LLM caution and retry logic.
list_accounts returns an unbounded list with no pagination. No page/offset parameters, no limit, no total count. If the bank has 10000+ accounts, the response will bloat context and degrade LLM reasoning.
Parameter descriptions lack format/constraint detail. 'Amount to deposit (must be positive)' is stated in description but not enforced in schema, no minimum bound, no regex pattern, no examples. LLMs cannot reliably extract and validate constraints from prose.
No idempotency guarantees documented. Temporal workflows have unique IDs (uuid-based) but the tool contract doesn't promise idempotent semantics. If an LLM retries due to timeout, will it create duplicate accounts/transfers?