A Model Context Protocol server for personal finance data aggregation via Plaid API, providing tools to query accounts, balances, transactions, investments, and liabilities across linked financial institutions.
The server implements 6 read-only financial data tools with fastMCP, using HTTP transport and tool annotations. Naming is verb-first and consistent (list_accounts, get_balances, get_transactions, get_recurring_transactions, get_liabilities, get_investments). Descriptions are present but vary in quality and length. Input schemas are visible in code but inconsistently detailed. All tools are READ_ONLY, reducing error-handling complexity, but output schemas are not formally documented in the server definition. Tool annotations (readOnlyHint=True) are correctly applied to all tools, following current spec patterns.
Get live current + available balances for accounts. Args: account_ids: Optional filter. When omitted, returns balances for every account across every healthy Item. When provided, only matching accounts are returned; Items that don't own any of the IDs emit a warning (INVALID_ACCOUNT_ID) rather than failing the call. Returns: {"accounts": [...], "warnings": [...]}.
Return holdings and transactions from investment accounts across all linked Items. For Items where the investments product is not enabled, a per-Item warning with code PRODUCTS_NOT_SUPPORTED is emitted instead of failing the call.
Return credit, student-loan, and mortgage liability details across all linked Items. For Items where the liabilities product is not enabled, a per-Item warning with code PRODUCTS_NOT_SUPPORTED is emitted instead of failing the call.
Return recurring inflow and outflow streams across all linked Items. Calls /accounts/get first per Item to collect account IDs (required by /transactions/recurring/get), then fetches recurring streams and shapes them into unified inflows/outflows lists. Returns: {"inflows": [...], "outflows": [...], "warnings": [...]}
Output schemas not formally documented. Tool descriptions explain return structure in prose (e.g. '{"accounts": [...], "warnings": [...]}'), but no JSON Schema definition is visible in the server registration code. LLMs cannot reliably parse prose schemas for downstream tool chaining.
Parameter descriptions lack constraint detail. E.g., 'start_date' in get_transactions says 'Start date in ISO YYYY-MM-DD format' but does not specify: what is the earliest allowed date? Is validation server-side? Does the API clip silently? Descriptions should include validation rules and failure modes.
Error handling guidance incomplete. While implementations catch Plaid ApiException and emit warnings, tool descriptions do not explain when errors are retryable or what the LLM should do on failure. E.g., 'PRODUCTS_NOT_SUPPORTED' and 'INVALID_ACCOUNT_ID' are mentioned but not formally defined as error codes the LLM should recognize.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 75 | <=2025-11-25 | v2 |
Fetch transactions in [start_date, end_date] across all healthy Items. Dates are ISO YYYY-MM-DD. Uses Plaid /transactions/get with offset pagination (count=500 per page). If start_date is older than ~2 years before end_date, the window is clipped and a warning is emitted.
List every account across all linked Items, with balances. Returns: {"accounts": [...], "warnings": [...]}. Warnings describe Items that are unhealthy (re-auth required, etc.) or hit API errors on this call.
Account ID parameter requires system ID, not human-friendly names. get_balances accepts 'account_ids' as a list of opaque strings with no guidance on how to obtain a valid account_id. LLMs must first call list_accounts to discover IDs, adding a discovery step. Consider accepting account names or descriptions as an alternative.
get_transactions pagination design is implicit. Implementation uses offset/count pagination internally (visible in code: 'offset', 'count=500'), but the tool interface does not expose pagination parameters (no 'limit' or 'offset' input). LLMs cannot control result size or fetch subsequent pages; they must accept whatever the tool returns (up to ~2 years of transactions). This can blow context windows.
Tool composition assumes static Plaid token setup. All tools iterate over 'all_items(api)', the set of linked accounts is hardcoded via environment variables (env_key). There is no tool to add/remove linked accounts or switch between different Plaid instances. For multi-user or multi-tenant scenarios, the toolset is incomplete.