Skip to main content
Glama
klauern

MCP YNAB Server

by klauern

get_transactions_needing_attention

Identify transactions requiring review in your YNAB budget by filtering uncategorized or unapproved items from recent activity.

Instructions

List transactions that need attention based on specified filter type in a YNAB budget.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
budget_idYes
filter_typeNoType of transactions to show. One of: 'uncategorized', 'unapproved', 'both'both
days_backNoNumber of days to look back (default 30, None for all)

Implementation Reference

  • The primary handler function for the 'get_transactions_needing_attention' MCP tool. It uses YNAB API to retrieve transactions, applies filters for uncategorized/unapproved based on input, formats into a markdown table using helper functions.
    @mcp.tool() async def get_transactions_needing_attention( budget_id: str, filter_type: Annotated[ str, Field( description="Type of transactions to show. One of: 'uncategorized', 'unapproved', 'both'" ), ] = "both", days_back: Annotated[ Optional[int], Field(description="Number of days to look back (default 30, None for all)") ] = 30, ) -> str: """List transactions that need attention based on specified filter type in a YNAB budget.""" filter_type = filter_type.lower() if filter_type not in ["uncategorized", "unapproved", "both"]: return "Error: Invalid filter_type. Must be 'uncategorized', 'unapproved', or 'both'" async with await get_ynab_client() as client: transactions_api = TransactionsApi(client) accounts_api = AccountsApi(client) accounts_response = accounts_api.get_accounts(budget_id) account_map = { account.id: account.name for account in accounts_response.data.accounts if not account.closed and not account.deleted } since_date = (datetime.now() - timedelta(days=days_back)).date() if days_back else None response = transactions_api.get_transactions(budget_id, since_date=since_date) needs_attention = _filter_transactions(response.data.transactions, filter_type) markdown = f"# Transactions Needing Attention ({filter_type.title()})\n\n" if not needs_attention: return markdown + "_No transactions need attention._" markdown += "**Filters Applied:**\n" markdown += f"- Filter type: {filter_type}\n" if days_back: markdown += f"- Looking back {days_back} days\n" markdown += "\n" headers = ["ID", "Date", "Account", "Amount", "Payee", "Status", "Memo"] align = ["left", "left", "left", "right", "left", "left", "left"] rows = [_get_transaction_row(txn, account_map, filter_type) for txn in needs_attention] markdown += _build_markdown_table(rows, headers, align) return markdown
  • Helper function used by the handler to filter transactions that are uncategorized and/or unapproved.
    def _filter_transactions( transactions: List[TransactionDetail], filter_type: str ) -> List[TransactionDetail]: """Filter transactions based on the filter type.""" needs_attention = [] for txn in transactions: if isinstance(txn, TransactionDetail): needs_category = filter_type in ["uncategorized", "both"] and not txn.category_id needs_approval = filter_type in ["unapproved", "both"] and not txn.approved if needs_category or needs_approval: needs_attention.append(txn) return needs_attention
  • Helper function used by the handler to format individual transactions into markdown table rows, including status flags.
    def _get_transaction_row( txn: TransactionDetail, account_map: Dict[str, str], filter_type: str ) -> List[str]: """Format a transaction into a row for the markdown table.""" amount_dollars = float(txn.amount) / 1000 amount_str = f"${abs(amount_dollars):,.2f}" if amount_dollars < 0: amount_str = f"-{amount_str}" status = [] if not txn.category_id: status.append("Uncategorized") if not txn.approved: status.append("Unapproved") return [ txn.id, txn.var_date.strftime("%Y-%m-%d"), account_map.get(txn.account_id, "Unknown"), amount_str, txn.payee_name or "N/A", ", ".join(status), txn.memo or "", ]
  • Pydantic schema definitions for the tool's input parameters using Annotated and Field.
    budget_id: str, filter_type: Annotated[ str, Field( description="Type of transactions to show. One of: 'uncategorized', 'unapproved', 'both'" ), ] = "both", days_back: Annotated[ Optional[int], Field(description="Number of days to look back (default 30, None for all)") ] = 30, ) -> str:
  • MCP tool registration decorator applied to the handler function.
    @mcp.tool()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/klauern/mcp-ynab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server