list_expenses
Retrieve and filter expense data by user, client, project, billing status, and date ranges to track spending and generate reports.
Instructions
Retrieve expenses with filtering by user, client, project, billing status, and date ranges. Returns paginated results with expense details.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | Filter by user ID | |
| client_id | No | Filter by client ID | |
| project_id | No | Filter by project ID | |
| is_billed | No | Filter by billing status | |
| is_closed | No | Filter by closed status | |
| from | No | Start date for date range filter (YYYY-MM-DD) | |
| to | No | End date for date range filter (YYYY-MM-DD) | |
| updated_since | No | Filter by expenses updated since this timestamp | |
| page | No | Page number for pagination | |
| per_page | No | Number of expenses per page (max 2000) |
Implementation Reference
- src/tools/expenses.ts:21-37 (handler)The handler class that executes the logic for 'list_expenses' by invoking the Harvest API client.
class ListExpensesHandler implements ToolHandler { constructor(private readonly config: BaseToolConfig) {} async execute(args: Record<string, any>): Promise<CallToolResult> { try { const validatedArgs = validateInput(ExpenseQuerySchema, args, 'expense query'); logger.info('Listing expenses from Harvest API'); const expenses = await this.config.harvestClient.getExpenses(validatedArgs); return { content: [{ type: 'text', text: JSON.stringify(expenses, null, 2) }], }; } catch (error) { return handleMCPToolError(error, 'list_expenses'); } } } - src/tools/expenses.ts:135-157 (registration)Registration of the 'list_expenses' tool, including its schema and handler association.
{ tool: { name: 'list_expenses', description: 'Retrieve expenses with filtering by user, client, project, billing status, and date ranges. Returns paginated results with expense details.', inputSchema: { type: 'object', properties: { user_id: { type: 'number', description: 'Filter by user ID' }, client_id: { type: 'number', description: 'Filter by client ID' }, project_id: { type: 'number', description: 'Filter by project ID' }, is_billed: { type: 'boolean', description: 'Filter by billing status' }, is_closed: { type: 'boolean', description: 'Filter by closed status' }, from: { type: 'string', format: 'date', description: 'Start date for date range filter (YYYY-MM-DD)' }, to: { type: 'string', format: 'date', description: 'End date for date range filter (YYYY-MM-DD)' }, updated_since: { type: 'string', format: 'date-time', description: 'Filter by expenses updated since this timestamp' }, page: { type: 'number', minimum: 1, description: 'Page number for pagination' }, per_page: { type: 'number', minimum: 1, maximum: 2000, description: 'Number of expenses per page (max 2000)' }, }, additionalProperties: false, }, }, handler: new ListExpensesHandler(config), },