Skip to main content
Glama
expense-create.ts4.39 kB
/** * expense_create Tool * * Create a new business expense in FreshBooks. */ import { z } from 'zod'; import { ExpenseCreateInputSchema, 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_create */ export const expenseCreateTool = { name: 'expense_create', description: `Create a new business expense in FreshBooks. WHEN TO USE: - User wants to record a business expense - User says "add expense", "create expense", "log expense" - Recording receipts or vendor payments - Tracking billable client expenses REQUIRED: - accountId: FreshBooks account ID (get from auth_status if not specified) - categoryId: Expense category (use expensecategory_list to see options) - staffId: Staff member who incurred the expense - date: When the expense occurred (ISO 8601 format) - amount: Expense amount with currency code OPTIONAL BUT HELPFUL: - vendor: Who was paid (vendor/merchant name) - notes: What the expense was for - clientId: Client to bill (makes expense billable) - projectId: Associated project (for project expense tracking) - markupPercent: Markup percentage when billing to client (0-100) - taxName1/taxPercent1: First tax (e.g., "GST", "5") - taxName2/taxPercent2: Second tax (e.g., "PST", "7") EXAMPLE PROMPTS: - "Add a $150 office supplies expense from Staples" - "Record a $500 travel expense for client project Alpha" - "Create an expense: $85 for software subscription, category 12" - "Log a client lunch expense for $67.50 with 15% tax" RETURNS: Created expense with ID and all details.`, inputSchema: ExpenseCreateInputSchema, outputSchema: ExpenseSingleOutputSchema, /** * Execute the tool */ async execute( input: z.infer<typeof ExpenseCreateInputSchema>, client: FreshBooksClientWrapper ): Promise<z.infer<typeof ExpenseSingleOutputSchema>> { const handler = ErrorHandler.wrapHandler( 'expense_create', async ( input: z.infer<typeof ExpenseCreateInputSchema>, _context: ToolContext ) => { const { accountId, ...expenseData } = input; logger.debug('Creating expense', { accountId, categoryId: expenseData.categoryId, amount: expenseData.amount, }); // Build expense object for API (convert camelCase to snake_case) const expense: Record<string, unknown> = { categoryid: expenseData.categoryId, staffid: expenseData.staffId, date: expenseData.date, amount: expenseData.amount, }; // Add optional fields if provided if (expenseData.vendor !== undefined) expense.vendor = expenseData.vendor; if (expenseData.notes !== undefined) expense.notes = expenseData.notes; if (expenseData.clientId !== undefined) expense.clientid = expenseData.clientId; if (expenseData.projectId !== undefined) expense.projectid = expenseData.projectId; if (expenseData.markupPercent !== undefined) expense.markup_percent = expenseData.markupPercent; if (expenseData.taxName1 !== undefined) expense.taxName1 = expenseData.taxName1; if (expenseData.taxPercent1 !== undefined) expense.taxPercent1 = expenseData.taxPercent1; if (expenseData.taxName2 !== undefined) expense.taxName2 = expenseData.taxName2; if (expenseData.taxPercent2 !== undefined) expense.taxPercent2 = expenseData.taxPercent2; const result = await client.executeWithRetry( 'expense_create', async (fbClient) => { const response = await fbClient.expenses.create(expense as any, accountId); if (!response.ok) { throw response.error; } return response.data; } ); // FreshBooks returns: { expense: { ... } } const createdExpense = (result as { expense?: unknown }).expense ?? result; logger.info('Expense created successfully', { expenseId: (createdExpense as { id?: number }).id, }); return createdExpense 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