ynab-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ynab-mcp what's my remaining dining out budget this month?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ynab-mcp
Your YNAB budget as MCP tools, reachable from every Claude client (Claude Code, Desktop, claude.ai and mobile), behind a password + TOTP login.
The tools are mcp-ynab by
Michael Green, installed unchanged from PyPI at the version uv.lock pins.
Upstream serves them over stdio only, which no phone or browser can reach. This
project adds the two things a hosted server needs:
Streamable HTTP at
/mcp, served by uvicorn.OAuth 2.1 with a password + TOTP login, which claude.ai and the mobile apps need to add it as a connector. The token behind it can edit the budget, so the server refuses to start without both factors. The OAuth code is shared with anki-mcp and obsidian-mcp.
How it reuses upstream
Upstream builds an MCPServer and registers its tools on it at import time.
src/ynab_mcp/server.py imports that, takes its tool list and passes it to a new
MCPServer that has auth configured. No tool code is copied or changed. Reading
the tool list touches one private SDK attribute; tests/test_server.py checks
that every tool upstream exports is still served, so a breaking bump fails CI.
Related MCP server: mcp-ynab
Run it
docker run -d --name ynab-mcp \
--env-file secrets.env \
-e YNAB_MCP_PUBLIC_URL=https://ynab.example.ts.net \
-v "$PWD/data:/data" \
-p 127.0.0.1:8790:8790 \
ghcr.io/jasonsooter/ynab-mcp:mainvariable | default | meaning |
| required | YNAB personal access token |
| required | login password, ≥ 12 characters |
| required | base32 TOTP setup key |
|
| the public HTTPS URL; feeds OAuth discovery |
|
| holds |
|
| listen port |
/data must persist. Without it, every device has to add the connector again
after a restart. Put the endpoint behind HTTPS (e.g. Tailscale Funnel) before
adding it to Claude, and add it as https://<host>/mcp.
Develop
uv sync
uv run pytestCI runs the tests, then builds the image for amd64 and arm64, and pushes it to
ghcr.io/jasonsooter/ynab-mcp on main (tags main and sha-<commit>).
License
AGPL-3.0-only, the same as upstream mcp-ynab, whose code the image contains.
Available Tools
47 toolscreate_accountA
Create a new account.
Args: plan_id: The plan ID (use list_plans to find available IDs) name: The name of the account type: The type of account ('checking', 'savings', 'cash', 'creditCard', 'lineOfCredit', 'otherAsset', 'otherLiability', 'mortgage', 'autoLoan', 'studentLoan', 'personalLoan', 'medicalDebt', 'otherDebt') balance: The current balance in dollars (e.g. 1000.00) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: name (required), type (required), balance (required), plan_id (required), +1 more. Returns: result
create_categoryA
Create a new category in a category group.
Args: plan_id: The plan ID (use list_plans to find available IDs) category_group_id: The category group ID to create the category in name: The name of the new category note: Optional note for the category goal_target: Optional goal target amount in dollars. If specified and no goal exists, a monthly 'Needed for Spending' goal will be created. goal_target_date: Optional goal target date in ISO format (e.g. '2026-12-01') exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: name (required), plan_id (required), category_group_id (required), note, +3 more. Returns: result
create_category_groupA
Create a new category group.
Args: plan_id: The plan ID (use list_plans to find available IDs) name: The name of the category group (max 50 characters) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: name (required), plan_id (required), exclude_fields. Returns: result
create_scheduled_transactionA
Create a scheduled transaction (a transaction with a future date).
Splits are not supported on this endpoint. Date must be in the future, no more than 5 years out.
Args: plan_id: The plan ID (use list_plans to find available IDs) account_id: The account ID for this scheduled transaction date: Future date in YYYY-MM-DD format (no more than 5 years out) amount: Amount in dollars (negative for outflow, positive for inflow). e.g. -50.25 for spending $50.25 payee_id: Payee ID (use list_payees to find available IDs). For account transfers, use the target account's transfer_payee_id. payee_name: Payee name. If payee_id is null, this resolves to an existing payee or creates a new one. category_id: Category ID. Credit Card Payment categories are not permitted. memo: Memo/note (max 500 chars) flag_color: 'red', 'orange', 'yellow', 'green', 'blue', 'purple', or null frequency: One of 'never', 'daily', 'weekly', 'everyOtherWeek', 'twiceAMonth', 'every4Weeks', 'monthly', 'everyOtherMonth', 'every3Months', 'every4Months', 'twiceAYear', 'yearly', 'everyOtherYear' exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: date (required), plan_id (required), account_id (required), memo, +7 more. Returns: result
create_transactionA
Create a new transaction. Future-dated transactions are not permitted (use scheduled transactions instead).
Args: plan_id: The plan ID (use list_plans to find available IDs) account_id: The account ID for this transaction date: Transaction date in YYYY-MM-DD format (must not be in the future) amount: Amount in dollars (negative for outflow, positive for inflow). e.g. -50.25 for spending $50.25 payee_id: Payee ID (use list_payees to find available IDs). For account transfers, use the target account's transfer_payee_id. payee_name: Payee name. If payee_id is null, this resolves to an existing payee or creates a new one. category_id: Category ID. Use null with subtransactions to create a split. Credit Card Payment categories are ignored. memo: Memo/note (max 500 chars) cleared: 'cleared', 'uncleared', or 'reconciled' approved: Whether the transaction is approved flag_color: 'red', 'orange', 'yellow', 'green', 'blue', 'purple', or null import_id: Unique import identifier (max 36 chars). Used for matching against imported transactions. subtransactions: For splits, an array of dicts with keys: amount (dollars, required), payee_id, payee_name, category_id, memo exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: date (required), amount (required), plan_id (required), account_id (required), +10 more. Returns: result
create_transactionsA
Create multiple transactions in a single API call. Ideal for bulk imports.
Future-dated transactions are not permitted. The response includes any duplicate_import_ids that were rejected because of an existing import_id on the same account.
Args: plan_id: The plan ID (use list_plans to find available IDs) account_id: Default account ID for all transactions transactions: List of transaction dicts, each with: - date: Transaction date in YYYY-MM-DD format (required) - amount: Amount in dollars (required, negative for outflow, positive for inflow) - account_id: (optional) Override the default account ID - payee_id: (optional) Payee ID - payee_name: (optional) Payee name (resolves to existing or creates a new payee) - category_id: (optional) Category ID. Use null with subtransactions for splits. - memo: (optional) Memo (max 500 chars) - cleared: (optional) 'cleared', 'uncleared', or 'reconciled' (default: 'uncleared') - approved: (optional) Whether the transaction is approved (default: false) - flag_color: (optional) 'red', 'orange', 'yellow', 'green', 'blue', 'purple', or null - import_id: (optional) Unique import identifier (max 36 chars) - subtransactions: (optional) For splits, a list of subtransaction dicts with: amount, payee_id, payee_name, category_id, memo exclude_fields: Optional list of field names to exclude from each created transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), account_id (required), transactions (required), exclude_fields. Returns: result
delete_scheduled_transactionA
Delete a scheduled transaction.
Args: scheduled_transaction_id: The scheduled transaction ID to delete plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), scheduled_transaction_id (required), exclude_fields. Returns: result
delete_transactionA
Delete a transaction.
Args: transaction_id: The transaction ID to delete plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), transaction_id (required), exclude_fields. Returns: result
get_accountA
Get details for a specific account.
Args: account_id: The account ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), account_id (required), exclude_fields. Returns: result
get_categoryA
Get a single category. Amounts are specific to the current plan month (UTC).
Args: category_id: The category ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), category_id (required), exclude_fields. Returns: result
get_category_for_monthA
Get category details for a specific month.
Args: category_id: The category ID month: Month in YYYY-MM-DD format (use first of month, e.g. '2026-03-01') plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: month (required), plan_id (required), category_id (required), exclude_fields. Returns: result
get_money_flowA
Build Sankey chart data showing money flow from income sources to spending category groups.
Returns nodes and index-based links suitable for Sankey/flow visualizations.
Args: plan_id: The plan ID (use list_plans to find available IDs) month: Month in YYYY-MM-DD format (first of month, e.g. '2026-03-01') or 'current'
Inputs: plan_id (required), month. Returns: result
get_money_movement_groups_for_monthA
Get all money movement groups for a specific month.
Args: month: Month in YYYY-MM-DD format (first of month) or 'current' plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each group. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: month (required), plan_id (required), exclude_fields. Returns: result
get_money_movements_for_monthA
Get all money movements for a specific month.
Args: month: Month in YYYY-MM-DD format (first of month) or 'current' plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each movement. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: month (required), plan_id (required), exclude_fields. Returns: result
get_monthA
Get detailed plan month summary including all categories. Use 'current' for the current month.
Args: month: Month in YYYY-MM-DD format (first of month) or 'current' plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: month (required), plan_id (required), exclude_fields. Returns: result
get_payeeA
Get a single payee.
Args: payee_id: The payee ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), payee_id (required), exclude_fields. Returns: result
get_payee_locationB
Get a single payee location.
Args: payee_location_id: The payee location ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), payee_location_id (required), exclude_fields. Returns: result
get_payee_locations_by_payeeB
Get all locations for a specific payee.
Args: payee_id: The payee ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each location. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), payee_id (required), exclude_fields. Returns: result
get_planA
Get details for a specific plan.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
get_plan_settingsA
Get settings for a plan (date format and currency format).
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
get_scheduled_transactionA
Get a single scheduled transaction.
Args: scheduled_transaction_id: The scheduled transaction ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), scheduled_transaction_id (required), exclude_fields. Returns: result
get_spending_by_categoryA
Get per-category spending breakdown for a month, with budget vs actual comparison.
Returns categories sorted by spending (highest first), grouped by category group, with budgeted, spent, balance, and percentage of total spending.
Args: plan_id: The plan ID (use list_plans to find available IDs) month: Month in YYYY-MM-DD format (first of month, e.g. '2026-03-01') or 'current'
Inputs: plan_id (required), month. Returns: result
get_transactionA
Get a specific transaction by ID.
Args: transaction_id: The transaction ID plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), transaction_id (required), exclude_fields. Returns: result
get_transactions_by_accountA
Get transactions for a specific account, excluding pending transactions.
Args: account_id: The account ID plan_id: The plan ID (use list_plans to find available IDs) since_date: Only return transactions on or after this date (YYYY-MM-DD) type: Filter by 'uncategorized' or 'unapproved' exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), account_id (required), type, since_date, +1 more. Returns: result
get_transactions_by_categoryA
Get all transactions for a specific category, excluding pending transactions.
Returns hybrid transactions which may represent regular transactions or subtransactions of split transactions. Each result includes a 'type' field ('transaction' or 'subtransaction') and 'parent_transaction_id' (set on subtransactions only).
Args: category_id: The category ID plan_id: The plan ID (use list_plans to find available IDs) since_date: Only return transactions on or after this date (YYYY-MM-DD) type: Filter by 'uncategorized' or 'unapproved' exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), category_id (required), type, since_date, +1 more. Returns: result
get_transactions_by_monthA
Get all transactions for a specific plan month, excluding pending transactions.
Args: month: Month in YYYY-MM-DD format (first of month) or 'current' plan_id: The plan ID (use list_plans to find available IDs) since_date: Only return transactions on or after this date (YYYY-MM-DD) type: Filter by 'uncategorized' or 'unapproved' exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: month (required), plan_id (required), type, since_date, +1 more. Returns: result
get_transactions_by_payeeA
Get all transactions for a specific payee, excluding pending transactions.
Returns hybrid transactions which may represent regular transactions or subtransactions of split transactions. Each result includes a 'type' field ('transaction' or 'subtransaction') and 'parent_transaction_id' (set on subtransactions only).
Args: payee_id: The payee ID plan_id: The plan ID (use list_plans to find available IDs) since_date: Only return transactions on or after this date (YYYY-MM-DD) type: Filter by 'uncategorized' or 'unapproved' exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), payee_id (required), type, since_date, +1 more. Returns: result
get_userA
Get the authenticated user's information.
Args: exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: exclude_fields. Returns: result
import_transactionsA
Import available transactions on all linked accounts for the given plan.
Equivalent to clicking 'Import' on each account in the YNAB web app or tapping the 'New Transactions' banner in the mobile app. Returns the list of transaction IDs that were imported.
Args: plan_id: The plan ID (use list_plans to find available IDs)
Inputs: plan_id (required). Returns: result
list_accountsA
List all accounts in a plan.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each account. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_categoriesA
List all categories grouped by category group.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each category group. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_money_movement_groupsA
List all money movement groups in a plan.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each group. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_money_movementsA
List all money movements in a plan.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each movement. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_monthsA
List all plan months.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each month. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_payee_locationsA
List all payee locations in a plan.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each location. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_payeesA
List all payees in a plan.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each payee. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_plansA
List all plans in the user's YNAB account. Call this first to get plan IDs.
Args: exclude_fields: Optional list of field names to exclude from each plan. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: exclude_fields. Returns: result
list_scheduled_transactionsA
List all scheduled (recurring) transactions.
Args: plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), exclude_fields. Returns: result
list_transactionsA
List transactions in a plan. Can filter by date and type.
Args: plan_id: The plan ID (use list_plans to find available IDs) since_date: Only return transactions on or after this date (YYYY-MM-DD) type: Filter by 'uncategorized' or 'unapproved' exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), type, since_date, exclude_fields. Returns: result
search_transactionsA
Search transactions by text across payee, memo, and category fields.
Args: plan_id: The plan ID (use list_plans to find available IDs) query: Text to search for (case-insensitive, matches payee, memo, and category) since_date: Only search transactions on or after this date (YYYY-MM-DD) amount_min: Minimum amount in dollars (e.g. -100.00). Filters by absolute value if both min and max are positive, otherwise by raw value. amount_max: Maximum amount in dollars (e.g. -10.00) exclude_fields: Optional list of field names to exclude from each transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: query (required), plan_id (required), amount_max, amount_min, +2 more. Returns: result
update_categoryA
Update a category. Only provide the fields you want to change.
Args: plan_id: The plan ID (use list_plans to find available IDs) category_id: The category ID to update name: New name for the category note: New note for the category category_group_id: Move category to a different category group goal_target: Goal target amount in dollars. If specified and no goal exists, a monthly 'Needed for Spending' goal will be created. goal_target_date: Goal target date in ISO format (e.g. '2026-12-01') exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), category_id (required), name, note, +4 more. Returns: result
update_category_for_monthB
Update the budgeted amount for a category in a specific month.
Args: category_id: The category ID month: Month in YYYY-MM-DD format (use first of month, e.g. '2026-03-01') budgeted: Budgeted amount in dollars (e.g. 500.00) plan_id: The plan ID (use list_plans to find available IDs) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: month (required), plan_id (required), budgeted (required), category_id (required), +1 more. Returns: result
update_category_groupA
Update a category group.
Args: plan_id: The plan ID (use list_plans to find available IDs) category_group_id: The category group ID to update name: New name for the category group (max 50 characters) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: name (required), plan_id (required), category_group_id (required), exclude_fields. Returns: result
update_payeeA
Update a payee.
Args: plan_id: The plan ID (use list_plans to find available IDs) payee_id: The payee ID to update name: New name for the payee (max 500 characters) exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: name (required), plan_id (required), payee_id (required), exclude_fields. Returns: result
update_scheduled_transactionA
Update a scheduled transaction.
The API requires account_id and date on every update. Splits are not supported on this endpoint. Date must be in the future, no more than 5 years out.
Args: plan_id: The plan ID (use list_plans to find available IDs) scheduled_transaction_id: The scheduled transaction ID to update account_id: The account ID for this scheduled transaction (required) date: Future date in YYYY-MM-DD format (required, no more than 5 years out) amount: Amount in dollars (negative for outflow, positive for inflow) payee_id: Payee ID. For account transfers, use the target account's transfer_payee_id. payee_name: Payee name (resolves to existing or creates a new payee) category_id: Category ID. Credit Card Payment categories are not permitted. memo: Memo/note (max 500 chars) flag_color: 'red', 'orange', 'yellow', 'green', 'blue', 'purple', or null frequency: One of 'never', 'daily', 'weekly', 'everyOtherWeek', 'twiceAMonth', 'every4Weeks', 'monthly', 'everyOtherMonth', 'every3Months', 'every4Months', 'twiceAYear', 'yearly', 'everyOtherYear' exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: date (required), plan_id (required), account_id (required), scheduled_transaction_id (required), +8 more. Returns: result
update_transactionA
Update an existing transaction. Only provide the fields you want to change.
Future-dated transactions are not permitted. Split transaction amounts and dates cannot be changed. If an existing transaction is a split, category_id cannot be changed and updating subtransactions is not supported.
Args: plan_id: The plan ID (use list_plans to find available IDs) transaction_id: The transaction ID to update account_id: New account ID date: New date (YYYY-MM-DD, must not be in the future) amount: New amount in dollars (negative for outflow, positive for inflow) payee_id: New payee ID. For account transfers, use target account's transfer_payee_id. payee_name: New payee name (resolves to existing or creates a new payee) category_id: New category ID. Use null with subtransactions to create a split. memo: New memo (max 500 chars) cleared: 'cleared', 'uncleared', or 'reconciled' approved: Whether the transaction is approved flag_color: 'red', 'orange', 'yellow', 'green', 'blue', 'purple', or null subtransactions: For creating a new split, list of dicts with: amount, payee_id, payee_name, category_id, memo exclude_fields: Optional list of field names to exclude from the response. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), transaction_id (required), date, memo, +10 more. Returns: result
update_transactionsA
Update multiple transactions in a single API call.
Each transaction must include either 'id' or 'import_id' for lookup (not both). Only provided fields are updated (sparse update). Ideal for bulk recategorization, bulk approval, bulk clearing, etc. Updating subtransactions on an existing split is not supported. Future-dated transactions are not permitted.
Args: plan_id: The plan ID (use list_plans to find available IDs) transactions: List of transaction dicts. Each must include EITHER: - id: The transaction ID OR - import_id: The transaction's import_id (used for lookup, cannot be changed) And optionally any of: - account_id: New account ID - date: New date (YYYY-MM-DD) - amount: New amount in dollars (negative for outflow, positive for inflow) - payee_id: New payee ID - payee_name: New payee name - category_id: New category ID (use null with subtransactions to create a split) - memo: New memo (max 500 chars) - cleared: 'cleared', 'uncleared', or 'reconciled' - approved: Whether the transaction is approved - flag_color: 'red', 'orange', 'yellow', 'green', 'blue', 'purple', or null - subtransactions: For creating a new split, list of dicts with: amount, payee_id, payee_name, category_id, memo exclude_fields: Optional list of field names to exclude from each updated transaction. If omitted, the model's default exclude list is used (see FIELDS.md). Pass [] to return all fields. Pass a custom list to override the default.
Inputs: plan_id (required), transactions (required), exclude_fields. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 47 tools
Most tools target a distinct resource+action, but there is a large family of transaction retrievers (list_transactions, get_transactions_by_account/category/month/payee, search_transactions) whose boundaries overlap and require careful reading to select correctly. Similarly, get_category vs get_category_for_month and the money-movement list/for_month pairs are close but distinguishable via their descriptions.
The dominant pattern is a clean verb_noun convention (get_plan, list_accounts, create_transaction, update_category, delete_transaction). However several tools deviate with 'by_x' / 'for_month' suffixes (get_transactions_by_account, get_category_for_month, get_money_movements_for_month) and the singular/plural bulk distinction (create_transaction vs create_transactions), which are minor inconsistencies.
At 47 tools the surface is very heavy and exceeds the threshold where counts start hurting selection. While YNAB is a broad domain, the count is inflated by consolidation opportunities (multiple transaction-fetch variants, separate money-movement/money-movement-group/month endpoints), pushing it beyond a well-scoped set.
Coverage is strong across plans, accounts, transactions (including bulk create/update and import), categories, category groups, payees, payee locations, months, scheduled transactions, and analytics (money flow, spending by category). Minor gaps exist, notably no delete_account, delete_category, delete_category_group, or explicit payee lifecycle operations.
Maintenance
Related MCP Connectors
Hosted remote MCP server for YNAB on Cloudflare Workers with OAuth
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
Host any HTTP API as MCP tools with a tamper-evident cross-agent settlement ledger.
MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server for interacting with YNAB (You Need A Budget). Provides tools for accessing budget data through MCP-enabled clients like Claude Desktop.4MIT
- AlicenseCqualityCmaintenanceFastMCP server that exposes the YNAB API for budget management, enabling interaction with YNAB data through MCP tools.441MIT
- FlicenseBqualityDmaintenanceA personal MCP server that gives Claude native access to YNAB budget data.46-
- AlicenseBqualityDmaintenanceA read-only MCP server for YNAB budgeting data, enabling daily/weekly/monthly expense reviews and planning support via Claude Desktop or Claude Code.4Apache 2.0