Skip to main content
Glama
expense-update.ts4.4 kB
/** * expense_update Tool * * Update an existing expense in FreshBooks. */ import { z } from 'zod'; import { ExpenseUpdateInputSchema, ExpenseSingleOutputSchema } from './schemas.js'; import { FreshBooksClientWrapper } from '../../client/index.js'; import { ErrorHandler } from '../../errors/error-handler.js'; import { ToolContext } from '../../errors/types.js'; import { logger } from '../../utils/logger.js'; /** * Tool definition for expense_update */ export const expenseUpdateTool = { name: 'expense_update', description: `Update an existing expense in FreshBooks. WHEN TO USE: - User wants to modify an existing expense - User says "update expense", "change expense", "edit expense" - Correcting expense details or amounts - Updating expense billing information - Archiving/deleting expenses (via visState) REQUIRED: - accountId: FreshBooks account ID (get from auth_status if not specified) - expenseId: ID of expense to update OPTIONAL FIELDS (only include what needs to change): - categoryId: Change expense category - date: Update expense date - amount: Modify expense amount/currency - vendor: Change vendor name - notes: Update description - clientId: Change client billing - projectId: Change project association - markupPercent: Adjust markup percentage (0-100) - taxName1/taxPercent1: Update first tax - taxName2/taxPercent2: Update second tax - visState: Archive or restore (0=active, 1=deleted, 2=archived) EXAMPLE PROMPTS: - "Update expense 12345 to $175.50" - "Change the vendor on expense 67890 to 'Acme Corp'" - "Update expense 11111: add client 99 for billing" - "Archive expense 54321" RETURNS: Updated expense with all current details.`, inputSchema: ExpenseUpdateInputSchema, outputSchema: ExpenseSingleOutputSchema, /** * Execute the tool */ async execute( input: z.infer<typeof ExpenseUpdateInputSchema>, client: FreshBooksClientWrapper ): Promise<z.infer<typeof ExpenseSingleOutputSchema>> { const handler = ErrorHandler.wrapHandler( 'expense_update', async ( input: z.infer<typeof ExpenseUpdateInputSchema>, _context: ToolContext ) => { const { accountId, expenseId, ...updateData } = input; logger.debug('Updating expense', { accountId, expenseId, fields: Object.keys(updateData), }); // Build expense update object (convert camelCase to snake_case) const expense: Record<string, unknown> = {}; // Add fields if provided if (updateData.categoryId !== undefined) expense.categoryid = updateData.categoryId; if (updateData.date !== undefined) expense.date = updateData.date; if (updateData.amount !== undefined) expense.amount = updateData.amount; if (updateData.vendor !== undefined) expense.vendor = updateData.vendor; if (updateData.notes !== undefined) expense.notes = updateData.notes; if (updateData.clientId !== undefined) expense.clientid = updateData.clientId; if (updateData.projectId !== undefined) expense.projectid = updateData.projectId; if (updateData.markupPercent !== undefined) expense.markup_percent = updateData.markupPercent; if (updateData.taxName1 !== undefined) expense.taxName1 = updateData.taxName1; if (updateData.taxPercent1 !== undefined) expense.taxPercent1 = updateData.taxPercent1; if (updateData.taxName2 !== undefined) expense.taxName2 = updateData.taxName2; if (updateData.taxPercent2 !== undefined) expense.taxPercent2 = updateData.taxPercent2; if (updateData.visState !== undefined) expense.vis_state = updateData.visState; const result = await client.executeWithRetry( 'expense_update', async (fbClient) => { const response = await fbClient.expenses.update(expense as any, accountId, String(expenseId)); if (!response.ok) { throw response.error; } return response.data; } ); // FreshBooks returns: { expense: { ... } } const updatedExpense = (result as { expense?: unknown }).expense ?? result; logger.info('Expense updated successfully', { expenseId, }); return updatedExpense as z.infer<typeof ExpenseSingleOutputSchema>; } ); return handler(input, { accountId: input.accountId }); }, };

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/Good-Samaritan-Software-LLC/freshbooks-mcp'

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