ynab_approve_transaction
Approve or unapprove a specific transaction in your YNAB budget to manage your financial records and maintain accurate budget tracking.
Instructions
Approves an existing transaction in your YNAB budget.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | The id of the budget containing the transaction (optional, defaults to the budget set in the YNAB_BUDGET_ID environment variable) | |
| transactionId | Yes | The id of the transaction to approve | |
| approved | No | Whether the transaction should be marked as approved |
Implementation Reference
- The main handler function that executes the tool logic: fetches the transaction, updates its approved status using YNAB API, handles errors, and returns formatted JSON response.export async function execute(input: ApproveTransactionInput, api: ynab.API) { try { const budgetId = getBudgetId(input.budgetId); // First, get the existing transaction to ensure we don't lose any data const existingTransaction = await api.transactions.getTransactionById(budgetId, input.transactionId); if (!existingTransaction.data.transaction) { throw new Error("Transaction not found"); } const existingTransactionData = existingTransaction.data.transaction; const transaction: ynab.PutTransactionWrapper = { transaction: { approved: input.approved ?? true, } }; const response = await api.transactions.updateTransaction( budgetId, existingTransactionData.id, transaction ); if (!response.data.transaction) { throw new Error("Failed to update transaction - no transaction data returned"); } return { content: [{ type: "text" as const, text: JSON.stringify({ success: true, transactionId: response.data.transaction.id, message: "Transaction updated successfully", }, null, 2) }] }; } catch (error) { console.error("Error approving transaction:", error); return { content: [{ type: "text" as const, text: JSON.stringify({ success: false, error: getErrorMessage(error), }, null, 2) }] }; } }
- src/index.ts:57-61 (registration)Registers the 'ynab_approve_transaction' tool with the MCP server, specifying title, description, input schema, and handler.server.registerTool(ApproveTransactionTool.name, { title: "Approve Transaction", description: ApproveTransactionTool.description, inputSchema: ApproveTransactionTool.inputSchema, }, async (input) => ApproveTransactionTool.execute(input, api));
- Zod-based input schema defining parameters for budgetId, transactionId, and approved flag.export const inputSchema = { budgetId: z.string().optional().describe("The id of the budget containing the transaction (optional, defaults to the budget set in the YNAB_BUDGET_ID environment variable)"), transactionId: z.string().describe("The id of the transaction to approve"), approved: z.boolean().optional().default(true).describe("Whether the transaction should be marked as approved"), };
- Helper function to resolve budget ID from input or environment variable, with validation.function getBudgetId(inputBudgetId?: string): string { const budgetId = inputBudgetId || process.env.YNAB_BUDGET_ID || ""; if (!budgetId) { throw new Error("No budget ID provided. Please provide a budget ID or set the YNAB_BUDGET_ID environment variable."); } return budgetId; }
- src/tools/errorUtils.ts:5-39 (helper)Shared utility function to extract meaningful error messages from errors, including YNAB API responses, used in the handler.export function getErrorMessage(error: unknown): string { // Handle standard Error objects if (error instanceof Error) { return error.message; } // Handle YNAB API error responses which have the structure: // { error: { id: '...', name: '...', detail: '...' } } if ( typeof error === 'object' && error !== null && 'error' in error && typeof (error as any).error === 'object' ) { const ynabError = (error as any).error; if (ynabError.detail) { return ynabError.detail; } if (ynabError.name) { return ynabError.name; } } // Fallback: try to stringify the error try { const stringified = JSON.stringify(error); if (stringified !== '{}') { return stringified; } } catch { // Ignore stringify errors } return 'Unknown error occurred'; }