personal-finance-mcp
This is a self-hosted, read-only MCP server that connects to your financial accounts via Plaid, enabling you to query your finances in natural language through an MCP client like Claude Code.
list_accounts: List every account across all linked banks with their balances.get_balances: Retrieve live current and available balances, optionally filtered by specific account IDs.get_transactions: Fetch transactions within a date range (up to ~2 years back), optionally filtered by account.search_transactions: Keyword search across merchant names, transaction names, and counterparty names within a date range.get_recurring_transactions: Identify recurring inflow and outflow streams (e.g., subscriptions, payroll).get_liabilities: View credit card, student loan, and mortgage details including APRs and payment information.get_investment_holdings: See current investment positions with ticker symbols, security names, and metadata.get_investment_transactions: Retrieve buy/sell/dividend history within a date range, joined with security metadata.get_institutions_status: Monitor the health of each linked financial institution, surfacing re-authentication needs or connectivity issues.
Provides read-only access to Chase bank accounts, including balances, transactions, and liabilities via the Plaid API.
personal-finance-mcp
Unofficial. This project is not affiliated with, endorsed by, or sponsored by Plaid Inc. "Plaid" is a trademark of Plaid Inc. This is a self-hosted client that talks to Plaid's API using credentials you supply.
A self-hosted, read-only MCP server that connects your banks, credit cards, loans, and brokerage accounts (via Plaid) to an MCP client like Claude Code. Ask questions about your own finances in plain English — no third-party aggregator (Monarch, Mint, etc.) involved.
What you can ask
"What's my total balance across all accounts?"
"Show me transactions over $100 in the last 30 days."
"Which subscriptions am I still paying for?"
"How much did I spend on groceries last month?"
"Any bank that needs re-authentication?"
Example session (illustrative):
you : What did I spend on groceries last month?
claude : [calls get_transactions]
$487.23 across 14 transactions. Top merchants:
Whole Foods ($198), Trader Joe's ($156), Safeway ($89).
you : Any subscriptions I'm still paying for?
claude : [calls get_recurring_transactions]
7 active recurring outflows totaling $142/mo:
Netflix ($15.99), Spotify ($11.99), NYT ($4), ...Related MCP server: FinLynq
Tools
All 9 tools are read-only. Each returns {<data>: [...], "warnings": [...]} so one broken bank doesn't break the whole query.
Tool | What it does |
| Every account across every linked bank, with balances |
| Live current + available balances (optionally filtered by account) |
| Transactions in a date range (up to 2 years back) |
| Keyword search across merchant / name / counterparty |
| Detected recurring inflow + outflow streams |
| Credit cards, student loans, mortgages with APRs and payment details |
| Current holdings with symbol + security metadata |
| Buy / sell / dividend history in a date range |
| Health of each linked bank (surfaces re-auth needs) |
Quickstart
Requires Python 3.11+, a Plaid account (free Trial plan), and an MCP client.
1. Plaid setup
Sign up at https://dashboard.plaid.com/signup → choose the Trial plan (free, 10 Items).
Team Settings → Products: enable Transactions, Liabilities, Investments.
Team Settings → API: copy your
client_idand productionsecret.
2. Install
git clone https://github.com/JosueM1109/personal-finance-mcp.git
cd personal-finance-mcp
python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then fill in PLAID_CLIENT_ID and PLAID_SECRET
pytest -v # sanity check3. Link each bank
Run once per bank you want to connect:
uvicorn link_helper:app --port 8765Open http://localhost:8765, click Link a bank, complete Plaid Link. The terminal prints a line like PLAID_TOKEN_CHASE=access-prod-xxx... — paste it into .env and repeat for each bank.
4. Run it
python server.py # serves on http://localhost:8000/mcp5. Add to Claude Code
claude mcp add --transport http personal-finance http://localhost:8000/mcpTry "list my accounts" to confirm.
Deployment
For a deployment you can use from anywhere:
Docker (included):
docker build -t personal-finance-mcp . && docker run --rm -p 8000:8000 --env-file .env personal-finance-mcpAny Python host (Fly.io, Railway, Raspberry Pi + Tailscale, a VPS): set the env vars from
.env.example, expose/mcpover HTTPS, gate it with auth.Prefect Horizon (what the author uses — $0 recurring cost): see docs/DEPLOYMENT.md for the full walkthrough.
Gate the endpoint. An exposed MCP endpoint with your tokens leaks every linked account. Use OAuth 2.1, Cloudflare Access, or bind to a private network only.
Security
Single-tenant. One deployment per person. Don't share.
Read-only. No tool mutates state at any institution. Don't add any that do.
Tokens live in env vars, never on disk.
.envis gitignored.You own Plaid compliance. You're the Plaid customer under your own account.
Before each deploy:
.envnever committed:git log --all -- .envreturns nothingNo real tokens in history:
git log -S'access-prod-' --allreturns only placeholdersAuth gate in front of the MCP endpoint (or localhost-only)
HORIZON=1(or similar) set in deployment env, blockinglink_helper.pythereCheck
get_institutions_status()every few weeks for re-auth needs
Troubleshooting
Tool returns empty despite real data. Plaid products weren't enabled when you linked the bank. Re-link with Transactions + Liabilities + Investments active. The tool surfaces PRODUCTS_NOT_SUPPORTED in warnings when this is the cause.
get_institutions_status() shows re_auth_required. The bank's Plaid session expired. Run link_helper.py in update mode — your existing access token stays the same. See docs/DEPLOYMENT.md.
Plaid Link shows a bank as "unsupported" (common with Amex). Usually an INSTITUTION_REGISTRATION_REQUIRED issue — OAuth banks need per-institution registration in the Plaid dashboard first. See docs/TROUBLESHOOTING.md.
More issues: docs/TROUBLESHOOTING.md.
Architecture
server.py — FastMCP server, 9 read-only tools.
plaid_client.py — Plaid SDK wrapper:
SecretStrtoken redaction, 5-minute per-Item health cache, response shaping, structured error mapping.link_helper.py — Local-only FastAPI app for Plaid Link. Refuses to run if
HORIZON=1is set.
Deeper dive (including why /transactions/get over /transactions/sync): docs/ARCHITECTURE.md.
Contributing
See CONTRIBUTING.md. Scope is deliberately narrow: read-only, single-tenant, Plaid-backed.
Available Tools
9 toolsget_balancesGet BalancesARead-only
Get live current + available balances for accounts.
| Name | Required | Description | Default |
|---|---|---|---|
| account_ids | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description adds minimal behavioral context. It mentions 'live current + available' but does not elaborate on rate limits, authentication, or implications of the optional 'account_ids' parameter (e.g., warnings).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One efficient sentence with no redundant words. Front-loaded with the primary purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single optional parameter and an output schema (not shown), the description is adequate. It covers the core purpose but could explain 'live' vs 'available' if not obvious from the output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the description adds no new meaning beyond the schema. The phrase 'live current + available' characterizes the data but not the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get'), the resource ('balances'), and the specific attributes ('live current + available'). This distinguishes it from sibling tools like 'list_accounts' or 'get_transactions'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like 'list_accounts' or 'get_investment_holdings'. Lacks context for when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_institutions_statusGet Institutions StatusARead-only
Return health status for every linked Item/institution.
No additional network calls beyond what all_items already makes (it
uses the 5-minute health cache). Enumerates linked Items and reports their
current health status.
Returns: {"items": [{"env_key", "institution", "institution_id", "status", "reason"}, ...]}
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, confirming safety. The description adds valuable behavioral context: uses a 5-minute health cache and makes no extra network calls, which helps agents understand cost and freshness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is extremely concise: two short paragraphs, no fluff, front-loaded with purpose. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, an output schema exists, and the description includes a return format example with all fields, it is fully sufficient. The caching behavior is also noted, making it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has zero parameters, so schema coverage is 100%. Description does not need to explain parameters; the only relevant detail is the cached nature, which is already mentioned elsewhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Return health status for every linked Item/institution.' The verb 'return' and resource are precise, and it distinguishes from sibling tools that deal with financial data like balances or transactions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides clear context: 'No additional network calls beyond what all_items already makes (it uses the 5-minute health cache).' This implies when to use it (when you need health status cheaply) but lacks explicit when-not or alternative recommendations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_investment_holdingsGet Investment HoldingsARead-only
Return investment holdings with security metadata across all linked Items.
Joins holdings with the securities list returned in the same response to provide symbol, name, and security type. Adds institution to each holding.
Returns: {"holdings": [...], "warnings": [...]}
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. Description adds value by explaining that it joins holdings with securities and adds institution info, providing context beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences plus a return format line. Every sentence is informative and no words are wasted. Front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and presence of output schema, description is complete. It explains the join operation and the return structure (holdings, warnings), sufficient for agent understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters defined, so baseline is 4. Description does not need to add parameter details, and it appropriately mentions what the tool returns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'Return' and resource 'investment holdings'. It specifies joining with securities list and adding institution. However, it does not explicitly distinguish from sibling tools like get_investment_transactions, but the name and context imply the difference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use vs alternatives. Usage is implied by the tool's name and description, but lacks when-not or alternative suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_investment_transactionsGet Investment TransactionsARead-only
Fetch investment transactions in [start_date, end_date] across all healthy Items.
Dates are ISO YYYY-MM-DD. Uses 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. Each transaction is joined with security metadata (ticker symbol, name) from the same response.
Returns: {"investment_transactions": [...], "warnings": [...]}
| Name | Required | Description | Default |
|---|---|---|---|
| start_date | Yes | ||
| end_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds significant details beyond readOnlyHint: fetches across all healthy Items, offset pagination, date clipping, and security metadata joining. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise but could be more front-loaded. Every sentence adds value; no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers pagination, date handling, security metadata, warnings, and return format. Output schema exists, so no need to detail return values further.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema: explains ISO format, clipping behavior for start_date, and that dates are inclusive. Schema has 0% description coverage, so description carries full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it fetches investment transactions within a date range across all healthy Items. Distinguishes from siblings like get_transactions (non-investment) and get_investment_holdings (holdings vs transactions).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides context on pagination and date window clipping. Does not explicitly state when not to use or alternatives, but the scope is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_liabilitiesGet LiabilitiesARead-only
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.
Returns: {"credit": [...], "student": [...], "mortgage": [...], "warnings": [...]}
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses that per-Item warnings are emitted instead of failure when the liabilities product is not enabled, adding valuable behavior context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences plus a return example provide all necessary information with no redundancy; front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and the output schema is provided, the description is complete, covering expected return fields and edge-case behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters and 100% schema coverage, the description doesn't need to add parameter meaning, and it appropriately focuses on the output structure, which is clear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns liability details for credit, student-loan, and mortgage across all linked Items, distinguishing it from sibling tools like get_balances or get_transactions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies broad usage across all Items but does not provide explicit guidance on when to use this tool versus alternatives or mention any prerequisites or limitations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recurring_transactionsGet Recurring TransactionsARead-only
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": [...]}
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses internal behavior (calling /accounts/get first) and output shaping, adding value beyond annotations which only indicate readOnlyHint. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with three sentences and a return block, each sentence earning its place, front-loaded with the main purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and an output schema exists, the description sufficiently covers the tool's behavior, internal API calls, and return shape, with no missing critical information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist (0 params, 100% schema coverage). The description adds meaning by explaining the underlying process, which compensates for the lack of parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns recurring inflow and outflow streams across all linked Items, with a specific verb and resource that distinguishes it from sibling tools like get_transactions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for recurring transactions but does not explicitly state when to use this tool vs alternatives like get_transactions or list_accounts. No when-not guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transactionsGet TransactionsARead-only
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.
| Name | Required | Description | Default |
|---|---|---|---|
| start_date | Yes | ||
| end_date | Yes | ||
| account_ids | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds critical details: date format (ISO YYYY-MM-DD), pagination (offset-based, count=500), date window clipping with warning emission. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences: purpose first, then technical specs. Every sentence adds value. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given output schema exists, return value details are unnecessary. The description covers date range, pagination, and constraints (healthy Items, clipping). Missing account_ids explanation and clarity on 'healthy Items' prevent a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description bears full burden. The start_date and end_date parameters are explained (format, clipping behavior), but account_ids is not described at all. This leaves a significant gap for the optional parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool fetches transactions in a date range 'across all healthy Items,' distinguishing it from siblings like search_transactions. The verb 'fetch' and resource 'transactions' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description specifies when to use (date range queries) and hints at usage conditions (healthy Items, pagination). However, it does not explicitly state when not to use or name alternative tools for filtered searches, which is a minor gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsList AccountsARead-only
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true. The description adds value by detailing the return format including warnings for unhealthy Items and API errors, which goes beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no fluff. The return format is included concisely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and presence of output schema (implied), the description is fully complete. It explains the output structure and warning semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters and 100% schema coverage, the description need not explain parameters. It appropriately focuses on the tool's behavior and output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' and resource 'accounts' with scope 'across all linked Items'. It clearly distinguishes from siblings like 'get_balances' which are more specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving all accounts, but does not explicitly state when to use this tool versus alternatives or provide exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_transactionsSearch TransactionsARead-only
Search transactions by keyword across merchant, name, and counterparty names.
Fetches transactions in [start_date, end_date] and filters them with a case-insensitive substring match against:
merchant_namenamecounterparties[].name
The match is performed on the raw Plaid payload before shaping so that
counterparty names (which are dropped by shape_transaction) are
searchable. Dates are ISO YYYY-MM-DD. The window is clipped to ~2 years
and a WINDOW_CLIPPED warning is emitted when applicable.
Returns: {"transactions": [...], "warnings": [...]}
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| start_date | Yes | ||
| end_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true. The description adds valuable behavioral details: case-insensitive substring match on raw Plaid payload, date formatting, window clipping, and warning emission. This goes beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bullet points, front-loaded purpose, and concise details. Every sentence adds value with no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the search algorithm, date handling, and warnings, the description is complete. Output schema exists, so return values are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 3 parameters with 0% description coverage. The description explains that query is a keyword substring match, dates are ISO YYYY-MM-DD, and window is clipped to ~2 years, adding significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches transactions by keyword across merchant, name, and counterparty names. It distinguishes from siblings like get_transactions which likely retrieves all transactions without keyword filtering.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool: for keyword searching within a date range. It doesn't explicitly exclude alternatives, but the context of sibling tools implies get_transactions is for unfiltered retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
get_balances - First observed
get_institutions_status - First observed
get_investment_holdings - First observed
get_investment_transactions - First observed
get_liabilities - First observed
get_recurring_transactions - First observed
get_transactions - First observed
list_accounts - First observed
search_transactions
TDQS
Scored across 9 tools
Each tool targets a distinct aspect of personal finance data (balances, transactions, investments, liabilities, etc.), with clear boundaries. There is no overlap in functionality; even transaction-related tools distinguish between regular, investment, recurring, and search operations.
All tools follow a consistent verb_noun pattern in snake_case, primarily using 'get_' for retrieval and 'list_' for accounts, which is predictable and unambiguous.
With 9 tools, the server is well-scoped for a personal finance data aggregator. Each tool serves a clear purpose without redundancy, covering core financial data retrieval needs.
The tool surface covers most essential read operations for personal finance: accounts, balances, transactions (multiple types), liabilities, and holdings. Minor gaps such as lack of categorization or income/expense summaries are acceptable for a focused data provider.
Maintenance
Related MCP Connectors
Query your real net worth, spending, transactions, budgets and portfolio from any MCP client.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Read-only bank & investment accounts via Plaid: balances, holdings, transactions, SQL analytics.
Personal finance for AI agents — onboard, import statements, categorize & budget over MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceA read-only MCP server that enables users to analyze their real bank, credit card, loan, and brokerage data through Plaid. It provides financial analysis tools for transactions, balances, investments, liabilities, and debt while keeping all access tokens and data locally stored.24MIT
- AlicenseCqualityAmaintenanceopen-source personal finance app with a first-party MCP server. 91 HTTP tools (OAuth 2.1 + DCR) and 87 stdio tools cover transactions, budgets, accounts, portfolio analytics, FX conversion, loans, subscriptions, goals, importers, and rules. Users self-host with Docker + PostgreSQL or use the managed cloud8913AGPL 3.0
- AlicenseNot gradedqualityDmaintenanceA local MCP server that provides read-only SQL access to financial accounts via Plaid, enabling natural language queries about transactions, balances, and holdings.MIT
- FlicenseNot gradedqualityBmaintenanceMCP server for personal finance via Open Finance, consolidating accounts and cards and answering spending questions with aggregated numbers. Provides tools for category spending, recurring subscriptions, budgets, card bills, and installment forecasts, with data stored locally in an encrypted SQLite database.1-