create_expense
Add expense entries to Harvest projects with category, cost, date, and receipt details to track project spending and billable costs.
Instructions
Create a new expense entry for a project with category and cost details. Supports receipt attachment and billable status.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | The user ID who incurred the expense | |
| project_id | Yes | The project ID to associate the expense with (required) | |
| expense_category_id | Yes | The expense category ID (required) | |
| spent_date | Yes | Date the expense was incurred (YYYY-MM-DD) (required) | |
| notes | No | Notes or description for the expense | |
| total_cost | Yes | Total cost of the expense (required) | |
| units | No | Number of units for unit-based expenses | |
| billable | No | Whether the expense is billable to the client |
Implementation Reference
- src/tools/expenses.ts:59-74 (handler)The CreateExpenseHandler class implements the logic for the 'create_expense' tool, validating input against CreateExpenseSchema and calling the harvestClient to perform the action.
class CreateExpenseHandler implements ToolHandler { constructor(private readonly config: BaseToolConfig) {} async execute(args: Record<string, any>): Promise<CallToolResult> { try { const validatedArgs = validateInput(CreateExpenseSchema, args, 'create expense'); logger.info('Creating expense via Harvest API'); const expense = await this.config.harvestClient.createExpense(validatedArgs); return { content: [{ type: 'text', text: JSON.stringify(expense, null, 2) }], }; } catch (error) { return handleMCPToolError(error, 'create_expense'); } } - src/schemas/expense.ts:97-106 (schema)Input validation schema for creating an expense.
export const CreateExpenseSchema = z.object({ user_id: z.number().int().positive().optional(), project_id: z.number().int().positive(), expense_category_id: z.number().int().positive(), spent_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format'), notes: z.string().optional(), total_cost: z.number().min(0), units: z.number().min(0).optional(), billable: z.boolean().optional().default(true), }); - src/tools/expenses.ts:173-185 (registration)Registration of the 'create_expense' tool, linking the name, schema, and handler.
{ tool: { name: 'create_expense', description: 'Create a new expense entry for a project with category and cost details. Supports receipt attachment and billable status.', inputSchema: { type: 'object', properties: { user_id: { type: 'number', description: 'The user ID who incurred the expense' }, project_id: { type: 'number', description: 'The project ID to associate the expense with (required)' }, expense_category_id: { type: 'number', description: 'The expense category ID (required)' }, spent_date: { type: 'string', format: 'date', description: 'Date the expense was incurred (YYYY-MM-DD) (required)' }, notes: { type: 'string', description: 'Notes or description for the expense' }, total_cost: { type: 'number', minimum: 0, description: 'Total cost of the expense (required)' },