Skip to main content
Glama

YNAB Assistant

by franccesco
categories.py11.4 kB
"""Category management tools for YNAB API.""" from typing import Annotated, Any import ynab from auth import get_api_client, get_api_configuration def get_categories( budget_id: Annotated[ str, "The ID of the budget to query. Use 'last-used' for the most recently " "accessed budget, or provide a specific budget ID.", ] = "last-used", last_knowledge_of_server: Annotated[ int | None, "The starting server knowledge for delta requests. If provided, only " "entities that have changed since this value will be included. Use None " "for full data.", ] = None, ) -> dict[str, Any]: """Get all categories for a budget grouped by category group. Retrieves all categories organized by their category groups. Use this tool to discover category IDs needed for transaction queries, budgeting operations, and category-specific analysis. Args: budget_id: The ID of the budget to query. Use 'last-used' for the most recently accessed budget, or provide a specific budget ID. last_knowledge_of_server: The starting server knowledge for delta requests. If provided, only entities that have changed since this value will be included. Use None for full data. Returns: dict[str, Any]: Categories grouped by category group with server knowledge for efficient delta synchronization. Raises: Exception: If the API call fails. """ configuration = get_api_configuration() with get_api_client(configuration) as api_client: api_instance = ynab.CategoriesApi(api_client) try: api_response = api_instance.get_categories( budget_id, last_knowledge_of_server=last_knowledge_of_server ) return api_response.data.model_dump() # type: ignore[attr-defined] except Exception as e: msg = f"Error fetching categories: {e!s}" raise Exception(msg) from e def get_category_by_id( category_id: Annotated[ str, "The ID of the category to retrieve. Use get_categories to discover " "available category IDs.", ], budget_id: Annotated[ str, "The ID of the budget to query. Use 'last-used' for the most recently " "accessed budget, or provide a specific budget ID.", ] = "last-used", ) -> dict[str, Any]: """Get a single category by its ID. Retrieves detailed information for a specific category. Amounts (budgeted, activity, balance, etc.) are specific to the current budget month (UTC). If you don't know the category ID, use get_categories first to list all categories and find the ID you need. Args: category_id: The ID of the category to retrieve. Use get_categories to discover available category IDs. budget_id: The ID of the budget to query. Use 'last-used' for the most recently accessed budget, or provide a specific budget ID. Returns: dict[str, Any]: Category data including budgeted amounts, activity, balance, and other category metadata for the current month. Raises: Exception: If the API call fails or category not found. """ configuration = get_api_configuration() with get_api_client(configuration) as api_client: api_instance = ynab.CategoriesApi(api_client) try: api_response = api_instance.get_category_by_id(budget_id, category_id) category = api_response.data.category # type: ignore[attr-defined] return category.model_dump() # type: ignore[attr-defined] except Exception as e: msg = f"Error fetching category: {e!s}" raise Exception(msg) from e def get_month_category_by_id( category_id: Annotated[ str, "The ID of the category to retrieve. Use get_categories to discover " "available category IDs.", ], month: Annotated[ str, "The budget month in ISO format YYYY-MM-DD (e.g., '2024-12-01') or " "'current' for the current month.", ], budget_id: Annotated[ str, "The ID of the budget to query. Use 'last-used' for the most recently " "accessed budget, or provide a specific budget ID.", ] = "last-used", ) -> dict[str, Any]: """Get a single category for a specific budget month. Retrieves detailed information for a specific category in a specific month. Amounts (budgeted, activity, balance, etc.) are specific to the specified budget month (UTC). Use this when you need historical category data or want to view category information for a month other than the current one. Args: category_id: The ID of the category to retrieve. Use get_categories to discover available category IDs. month: The budget month in ISO format YYYY-MM-DD (e.g., '2024-12-01') or 'current' for the current month. budget_id: The ID of the budget to query. Use 'last-used' for the most recently accessed budget, or provide a specific budget ID. Returns: dict[str, Any]: Category data for the specified month, including budgeted amounts, activity, and balance. Raises: Exception: If the API call fails or category not found. """ configuration = get_api_configuration() with get_api_client(configuration) as api_client: api_instance = ynab.CategoriesApi(api_client) try: api_response = api_instance.get_month_category_by_id( budget_id, month, category_id # type: ignore[arg-type] ) category = api_response.data.category # type: ignore[attr-defined] return category.model_dump() # type: ignore[attr-defined] except Exception as e: msg = f"Error fetching month category: {e!s}" raise Exception(msg) from e def update_category( category_id: Annotated[ str, "The ID of the category to update. Use get_categories to discover " "available category IDs.", ], budget_id: Annotated[ str, "The ID of the budget to query. Use 'last-used' for the most recently " "accessed budget, or provide a specific budget ID.", ] = "last-used", note: Annotated[ str | None, "The category note to set. Provide a string to update the note, or None " "to leave it unchanged.", ] = None, budgeted: Annotated[ int | None, "The budgeted amount in milliunits. Provide an integer to update the " "budgeted amount, or None to leave it unchanged.", ] = None, ) -> dict[str, Any]: """Update a category's budgeted amount and/or note for the current month. Amounts in YNAB are expressed in milliunits: 1000 milliunits = $1.00. For example, to budget $50.00, use 50000. Negative amounts are not typical for budgeted amounts. Updates apply to the current budget month. Args: category_id: The ID of the category to update. Use get_categories to discover available category IDs. budget_id: The ID of the budget to query. Use 'last-used' for the most recently accessed budget, or provide a specific budget ID. note: The category note to set. Provide a string to update the note, or None to leave it unchanged. budgeted: The budgeted amount in milliunits. Provide an integer to update the budgeted amount, or None to leave it unchanged. Returns: dict[str, Any]: Updated category data including the new budgeted amount and note. Raises: Exception: If the API call fails or category not found. """ configuration = get_api_configuration() with get_api_client(configuration) as api_client: api_instance = ynab.CategoriesApi(api_client) try: # Build category data with only provided fields category_data: dict[str, Any] = {} if note is not None: category_data["note"] = note if budgeted is not None: category_data["budgeted"] = budgeted # Create wrapper wrapper = ynab.PatchCategoryWrapper(category=category_data) # type: ignore[arg-type] api_response = api_instance.update_category(budget_id, category_id, wrapper) return api_response.data.model_dump() # type: ignore[attr-defined] except Exception as e: msg = f"Error updating category: {e!s}" raise Exception(msg) from e def update_month_category( category_id: Annotated[ str, "The ID of the category to update. Use get_categories to discover " "available category IDs.", ], month: Annotated[ str, "The budget month in ISO format YYYY-MM-DD (e.g., '2024-12-01') or " "'current' for the current month.", ], budgeted: Annotated[ int, "The budgeted amount in milliunits. This is the amount you want to " "allocate to this category for the specified month.", ], budget_id: Annotated[ str, "The ID of the budget to query. Use 'last-used' for the most recently " "accessed budget, or provide a specific budget ID.", ] = "last-used", ) -> dict[str, Any]: """Update a category's budgeted amount for a specific month. Amounts in YNAB are expressed in milliunits: 1000 milliunits = $1.00. For example, to budget $50.00, use 50000. Negative amounts are not typical for budgeted amounts. Only the budgeted amount can be updated for a specific month. Any other fields will be ignored by the API. Use this when you need to adjust budget allocations for past or future months. Args: category_id: The ID of the category to update. Use get_categories to discover available category IDs. month: The budget month in ISO format YYYY-MM-DD (e.g., '2024-12-01') or 'current' for the current month. budgeted: The budgeted amount in milliunits. This is the amount you want to allocate to this category for the specified month. budget_id: The ID of the budget to query. Use 'last-used' for the most recently accessed budget, or provide a specific budget ID. Returns: dict[str, Any]: Updated month category data including the new budgeted amount for the specified month. Raises: Exception: If the API call fails or category not found. """ configuration = get_api_configuration() with get_api_client(configuration) as api_client: api_instance = ynab.CategoriesApi(api_client) try: # Build category data (only budgeted is allowed) category_data = {"budgeted": budgeted} # Create wrapper wrapper = ynab.PatchMonthCategoryWrapper(category=category_data) # type: ignore[arg-type] api_response = api_instance.update_month_category( budget_id, month, category_id, wrapper # type: ignore[arg-type] ) return api_response.data.model_dump() # type: ignore[attr-defined] except Exception as e: msg = f"Error updating month category: {e!s}" raise Exception(msg) from e

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/franccesco/ynab-mcp'

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