Skip to main content
Glama
ynab-mcp

ynab-mcp

by JasonSooter

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:main

variable

default

meaning

YNAB_API_KEY

required

YNAB personal access token

YNAB_MCP_LOGIN_PASSWORD

required

login password, ≥ 12 characters

YNAB_MCP_TOTP_SECRET

required

base32 TOTP setup key

YNAB_MCP_PUBLIC_URL

http://localhost:8790

the public HTTPS URL; feeds OAuth discovery

YNAB_MCP_STATE_DIR

/data

holds oauth.db (connector logins) and cache.db (upstream's cache)

YNAB_MCP_PORT

8790

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 pytest

CI 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 tools
create_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

    A3.7/5.0

    Scored across 47 tools

    Disambiguation4/5

    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.

    Naming Consistency4/5

    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.

    Tool Count2/5

    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.

    Completeness4/5

    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

    ActivityMaintained
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A 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.
      4
      MIT
    • A
      license
      C
      quality
      C
      maintenance
      FastMCP server that exposes the YNAB API for budget management, enabling interaction with YNAB data through MCP tools.
      44
      1
      MIT
    • F
      license
      B
      quality
      D
      maintenance
      A personal MCP server that gives Claude native access to YNAB budget data.
      46
      -
    • A
      license
      B
      quality
      D
      maintenance
      A read-only MCP server for YNAB budgeting data, enabling daily/weekly/monthly expense reviews and planning support via Claude Desktop or Claude Code.
      4
      Apache 2.0