Skip to main content
Glama
Jtewen

You Need A Budget (YNAB) MCP

by Jtewen

manage-budgeted-amount

Allocate funds to specific categories or transfer money between them for a designated month. Use this tool to manage budgeted amounts effectively within your YNAB budget.

Instructions

Assign a budgeted amount to a category or move money between categories for a specific month. This is the primary tool for allocating funds.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesThe action to perform.
amountYesThe amount in milliunits.
budget_idNoThe ID of the budget. If not provided, the default budget will be used.
from_category_idNoThe ID of the category to move money from. Required for 'move' action.
monthYesThe month to apply the action to (YYYY-MM-DD).
to_category_idNoThe ID of the category to move money to, or the category to assign to.

Implementation Reference

  • Implements the core logic for the 'manage-budgeted-amount' tool. Handles input validation, 'assign' action by directly setting budgeted amount on a category, and 'move' action by fetching current category states, calculating new budgeted amounts, and updating both categories using ynab_client methods.
    elif name == "manage-budgeted-amount":
        args = ManageBudgetedAmountInput.model_validate(arguments or {})
        budget_id = await _get_budget_id(args.model_dump())
        amount = int(args.amount)
        month = args.month
        
        if args.action == "assign":
            await ynab_client.assign_budget_amount(
                budget_id=budget_id,
                month=month,
                category_id=args.to_category_id,
                amount=amount,
            )
            return [
                types.TextContent(
                    type="text",
                    text=f"Successfully assigned {amount / 1000:.2f} to category {args.to_category_id} for {month}.",
                )
            ]
        elif args.action == "move":
            from_cat = await ynab_client.get_month_category(budget_id, month, args.from_category_id)
            to_cat = await ynab_client.get_month_category(budget_id, month, args.to_category_id)
    
            new_from_budgeted = from_cat.budgeted - amount
            new_to_budgeted = to_cat.budgeted + amount
    
            await ynab_client.assign_budget_amount(budget_id, month, args.from_category_id, new_from_budgeted)
            await ynab_client.assign_budget_amount(budget_id, month, args.to_category_id, new_to_budgeted)
            
            return [
                types.TextContent(
                    type="text",
                    text=f"Successfully moved {amount / 1000:.2f} from category {from_cat.name} to {to_cat.name} for {month}.",
                )
            ]
  • Defines the Pydantic model ManageBudgetedAmountInput for input validation, including action enum, required fields for assign/move operations, and a validator to enforce field presence based on action.
    class ManageBudgetedAmountAction(str, Enum):
        ASSIGN = "assign"
        MOVE = "move"
    
    
    class ManageBudgetedAmountInput(BudgetIdInput):
        action: ManageBudgetedAmountAction = Field(..., description="The action to perform.")
        amount: float = Field(..., description="The amount in milliunits.")
        month: str = Field(..., description="The month to apply the action to (YYYY-MM-DD).")
        from_category_id: Optional[str] = Field(None, description="The ID of the category to move money from. Required for 'move' action.")
        to_category_id: Optional[str] = Field(None, description="The ID of the category to move money to, or the category to assign to.")
    
        @model_validator(mode='before')
        @classmethod
        def check_fields_for_action(cls, values):
            action = values.get('action')
            if not action:
                raise ValueError("'action' is a required field.")
    
            if action == 'assign':
                if not values.get('to_category_id'):
                    raise ValueError("'to_category_id' is required for the 'assign' action.")
                if values.get('from_category_id'):
                    raise ValueError("'from_category_id' should not be provided for the 'assign' action.")
            elif action == 'move':
                if not values.get('from_category_id') or not values.get('to_category_id'):
                    raise ValueError("'from_category_id' and 'to_category_id' are required for the 'move' action.")
            
            return values 
  • Registers the 'manage-budgeted-amount' tool in the list_tools handler, specifying name, description, and input schema from ManageBudgetedAmountInput.
    types.Tool(
        name="manage-budgeted-amount",
        description="Assign a budgeted amount to a category or move money between categories for a specific month. This is the primary tool for allocating funds.",
        inputSchema=ManageBudgetedAmountInput.model_json_schema(),
    ),

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

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