Skip to main content
Glama
klauern

MCP YNAB Server

by klauern

get_categories

Retrieve all transaction categories for a YNAB budget and display them in Markdown format to organize and analyze spending patterns.

Instructions

List all transaction categories for a given YNAB budget in Markdown format.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
budget_idYes

Implementation Reference

  • The primary handler for the 'get_categories' tool, registered via @mcp.tool() decorator. Fetches category groups from YNAB's CategoriesApi, processes each category's budgeted and activity amounts, formats into Markdown tables per group, and returns the formatted string.
    @mcp.tool()
    async def get_categories(budget_id: str) -> str:
        """List all transaction categories for a given YNAB budget in Markdown format."""
        async with await get_ynab_client() as client:
            categories_api = CategoriesApi(client)
            response = categories_api.get_categories(budget_id)
            groups = response.data.category_groups
    
            markdown = "# YNAB Categories\n\n"
            headers = ["Category ID", "Category Name", "Budgeted", "Activity"]
            align = ["left", "left", "right", "right"]
    
            for group in groups:
                if isinstance(group, CategoryGroupWithCategories):
                    categories_list = group.categories
                    group_name = group.name
                else:
                    group_dict = cast(Dict[str, Any], group.to_dict())
                    categories_list = group_dict["categories"]
                    group_name = group_dict["name"]
    
                if not categories_list:
                    continue
    
                markdown += f"## {group_name}\n\n"
                rows = []
    
                for category in categories_list:
                    cat_id, name, budgeted, activity = _process_category_data(category)
                    budgeted_dollars = float(budgeted) / 1000 if budgeted else 0
                    activity_dollars = float(activity) / 1000 if activity else 0
    
                    rows.append(
                        [
                            cat_id,
                            name,
                            _format_dollar_amount(budgeted_dollars),
                            _format_dollar_amount(activity_dollars),
                        ]
                    )
    
                table_md = _build_markdown_table(rows, headers, align)
                markdown += table_md + "\n"
            return markdown
  • Helper function used by get_categories to extract and type-convert id, name, budgeted, and activity from either Category model or dict.
    def _process_category_data(category: Category | Dict[str, Any]) -> tuple[str, str, float, float]:
        """Process category data and return tuple of (id, name, budgeted, activity)."""
        if isinstance(category, Category):
            return category.id, category.name, category.budgeted, category.activity
        cat_dict = cast(Dict[str, Any], category)
        return cat_dict["id"], cat_dict["name"], cat_dict["budgeted"], cat_dict["activity"]
  • Helper function used by get_categories to format budgeted and activity amounts as currency strings with negative sign prefix.
    def _format_dollar_amount(amount: float) -> str:
        """Format a dollar amount with proper sign and formatting."""
        amount_str = f"${abs(amount):,.2f}"
        return f"-{amount_str}" if amount < 0 else amount_str
  • General helper function used by get_categories (and others) to generate Markdown tables from row data, handling alignments and column widths.
    def _build_markdown_table(
        rows: List[List[str]], headers: List[str], alignments: Optional[List[str]] = None
    ) -> str:
        """Build a markdown table from rows and headers."""
        if not rows:
            return _get_empty_table(headers)
    
        alignments = alignments if alignments is not None else ["left"] * len(headers)
        col_count = len(headers)
        widths = _get_column_widths(headers, rows, col_count)
    
        header_line = _format_table_line(headers, widths, alignments)
        sep_line = "|" + "|".join("-" * (w + 1) for w in widths) + "|\n"
    
        row_lines = "".join(_format_table_line(row, widths, alignments) for row in rows)
        return header_line + sep_line + row_lines

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