ExpenseBot
Ce que fait ce MCP
Records and analyzes expenses, income, mileage, reports, invoices, client advances, and accounting-related activity.
Outils
Schéma d’entrée
{'type': 'object', 'required': ['total', 'date'], 'properties': {'tax': {'type': 'number', 'description': 'Tax amount'}, 'tip': {'type': 'number', 'description': 'Tip amount'}, 'city': {'type': 'string', 'description': 'City/location'}, 'date': {'type': 'string', 'format': 'date', 'description': 'Expense date (YYYY-MM-DD)'}, 'notes': {'type': 'string', 'description': 'Notes or description'}, 'total': {'type': 'number', 'description': 'Positive amount paid or received. ExpenseBot stores a client advance as negative.'}, 'category': {'type': 'string', 'description': 'A configured Expense Account returned by list_categories. Do not invent a category.'}, 'currency': {'type': 'string', 'description': 'Currency code (default: USD)'}, 'merchant': {'type': 'string', 'description': 'Merchant/vendor name for an ordinary expense. Not needed for a client advance; ExpenseBot derives it from clientName.'}, 'subtotal': {'type': 'number', 'description': 'Subtotal before tax'}, 'clientName': {'type': 'string', 'description': 'Client name for a client advance, in ordinary language. ExpenseBot resolves the canonical Client â\x80\x93 Name group.'}, 'isClientAdvance': {'type': 'boolean', 'description': 'True only when a client supplied money in advance for expenses. Requires clientName and does not require category.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'message'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'expense': {'type': 'object', 'properties': {'tag': {'type': 'string'}, 'date': {'type': 'string', 'format': 'date'}, 'total': {'type': 'number'}, 'category': {'type': 'string'}, 'currency': {'type': 'string'}, 'merchant': {'type': 'string'}, 'recordId': {'type': 'string'}, 'rowNumber': {'type': 'integer', 'minimum': 1}, 'receivedAmount': {'type': 'number'}, 'isClientAdvance': {'type': 'boolean'}}, 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'recordId': {'type': 'string'}, 'rowNumber': {'type': 'integer', 'minimum': 1}, 'finalAnswer': {'type': 'string'}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'responseGuidance': {'type': 'string'}, 'reviewExpensesUrl': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['amount', 'source', 'paymentMethod'], 'properties': {'tag': {'type': 'string', 'description': 'Tag for client/project attribution'}, 'date': {'type': 'string', 'format': 'date', 'description': 'Income date (YYYY-MM-DD). Defaults to today.'}, 'fees': {'type': 'number', 'description': 'Processor/transfer fees deducted'}, 'notes': {'type': 'string'}, 'amount': {'type': 'number', 'description': 'Income amount (>0)'}, 'source': {'type': 'string', 'description': 'Who paid you (client name, customer, etc.)'}, 'category': {'type': 'string', 'description': 'A category returned by list_income_categories (optional; defaults to Service income)'}, 'currency': {'type': 'string', 'description': 'Currency code (default: home currency)'}, 'reference': {'type': 'string', 'description': 'Invoice or transaction reference'}, 'description': {'type': 'string', 'description': 'What the income was for'}, 'taxCollected': {'type': 'number', 'description': 'Sales tax/GST/HST collected'}, 'paymentMethod': {'type': 'string', 'description': 'How you got paid. Canonical rails are Cash, Check, Bank transfer, Wallet app, Credit/Debit card, Payment processor, or Other; common labels such as Stripe and Venmo are normalized.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'message'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'deduped': {'type': 'boolean'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'recordId': {'type': 'string'}, 'rowNumber': {'type': 'integer', 'minimum': 1}, 'matchedRow': {'type': 'object', 'properties': {'date': {'type': 'string', 'format': 'date'}, 'amount': {'type': 'number'}, 'currency': {'type': 'string'}, 'rowNumber': {'type': 'integer', 'minimum': 1}}, 'additionalProperties': True}, 'tabCreated': {'type': 'boolean'}, 'finalAnswer': {'type': 'string'}, 'destinations': {'type': 'object', 'additionalProperties': True}, 'responseGuidance': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': [], 'properties': {'tag': {'type': 'string', 'description': 'Optional client/project tag. In step 1 it pre-fills the staged rows; in step 2 it applies to the confirmed selection.'}, 'confirm': {'type': 'boolean', 'description': 'Step 2 only: true writes the staged rows. Omit it (with previewId absent) to parse and preview without writing.'}, 'csvText': {'type': 'string', 'description': 'Legacy fallback for MCP clients that send raw CSV/TSV/text content inline. ChatGPT should use csvContent.'}, 'bulkNote': {'type': 'string', 'description': "Step 2 only: one note (max 120 chars) prepended to every confirmed row's Notes, same as the app's 'Add note to all entries'."}, 'rowEdits': {'type': 'array', 'items': {'type': 'object', 'required': ['index', 'fields'], 'properties': {'index': {'type': 'integer', 'description': 'Preview row index'}, 'fields': {'type': 'object', 'description': 'Only the user-approved income fields to replace on this staged row: date, source, amount, currency, category, paymentMethod, description, notes, reference, fees, taxCollected, or tag.', 'additionalProperties': True}}}, 'description': 'Step 2 only: user-approved corrections, at most 50 rows. Fields: date (ISO YYYY-MM-DD), source, amount, currency, category, paymentMethod, description, notes, reference, fees, taxCollected, tag.'}, 'previewId': {'type': 'string', 'description': 'Step 2 only: the previewId returned by the step-1 call.'}, 'csvContent': {'type': 'object', 'required': ['download_url', 'file_id'], 'properties': {'file_id': {'type': 'string', 'description': 'Attachment identifier supplied by ChatGPT.'}, 'file_name': {'type': 'string', 'description': 'Original attachment filename supplied by ChatGPT.'}, 'mime_type': {'type': 'string', 'description': 'Attachment MIME type supplied by ChatGPT.'}, 'download_url': {'type': 'string', 'format': 'uri', 'description': 'Temporary HTTPS URL supplied by ChatGPT for downloading the attachment.'}}, 'description': 'Attached CSV/TSV/text file supplied by ChatGPT for step 1. The server downloads and decodes the attachment securely.'}, 'paymentMethod': {'type': 'string', 'description': 'Fallback payment rail for rows where the parser found none (Cash, Check, Bank transfer, Wallet app, Credit/Debit card, Payment processor, or Other).'}, 'keepBothIndexes': {'type': 'array', 'items': {'type': 'integer'}, 'description': "Step 2 only: preview indexes of duplicate-flagged rows the user explicitly wants to keep anyway (the app's 'Keep Both')."}, 'selectedIndexes': {'type': 'array', 'items': {'type': 'integer'}, 'description': 'Step 2 only: preview row indexes to write. Omit to write all staged rows.'}}}
Schéma de sortie
{'type': 'object', 'allOf': [{'if': {'required': ['preview'], 'properties': {'preview': {'const': True}}}, 'then': {'required': ['previewId', 'expiresAt', 'entryCount', 'entries', 'confirmationContract']}}, {'if': {'required': ['confirmed'], 'properties': {'confirmed': {'const': True}}}, 'then': {'required': ['previewId', 'written', 'deduped', 'failed', 'unattempted', 'total']}}], 'required': ['success', 'message'], 'properties': {'total': {'type': 'integer', 'minimum': 0}, 'failed': {'type': 'integer', 'minimum': 0}, 'deduped': {'type': 'integer', 'minimum': 0}, 'entries': {'type': 'array', 'items': {'type': 'object', 'properties': {'date': {'type': 'string', 'format': 'date'}, 'index': {'type': 'integer', 'minimum': 0}, 'payer': {'type': 'string'}, 'amount': {'type': 'number'}, 'currency': {'type': 'string'}, 'duplicate': {'type': 'boolean'}}, 'additionalProperties': True}}, 'message': {'type': 'string'}, 'preview': {'type': 'boolean'}, 'success': {'type': 'boolean'}, 'written': {'type': 'integer', 'minimum': 0}, 'warnings': {'type': 'array', 'items': {'type': 'string'}}, 'confirmed': {'type': 'boolean'}, 'expiresAt': {'type': 'string', 'format': 'date-time'}, 'previewId': {'type': 'string'}, 'duplicates': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'entryCount': {'type': 'integer', 'minimum': 0}, 'finalAnswer': {'type': 'string'}, 'unattempted': {'type': 'integer', 'minimum': 0}, 'rejectedRows': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'duplicateCount': {'type': 'integer', 'minimum': 0}, 'maxChatEntries': {'type': 'integer', 'minimum': 1}, 'refundRowCount': {'type': 'integer', 'minimum': 0}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewImportUrl': {'type': 'string'}, 'reviewIncomeUrl': {'type': 'string'}, 'tooLargeForChat': {'type': 'boolean'}, 'expiresInMinutes': {'type': 'integer', 'minimum': 1}, 'idempotentReplay': {'type': 'boolean'}, 'responseGuidance': {'type': 'string'}, 'totalsByCurrency': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'projectionTruncated': {'type': 'boolean'}, 'confirmationContract': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': [], 'properties': {'tag': {'type': 'string', 'description': 'Optional client/project tag. In step 1 it pre-fills the staged rows; in step 2 it applies to the confirmed selection.'}, 'photo': {'type': 'object', 'required': ['download_url', 'file_id'], 'properties': {'file_id': {'type': 'string', 'description': 'Attachment identifier supplied by ChatGPT.'}, 'file_name': {'type': 'string', 'description': 'Original attachment filename supplied by ChatGPT.'}, 'mime_type': {'type': 'string', 'description': 'Attachment MIME type supplied by ChatGPT.'}, 'download_url': {'type': 'string', 'format': 'uri', 'description': 'Temporary HTTPS URL supplied by ChatGPT for downloading the attachment.'}}, 'description': 'Attached image or PDF supplied by ChatGPT for step 1. The server downloads and parses the attachment securely.'}, 'confirm': {'type': 'boolean', 'description': 'Step 2 only: true writes the staged rows. Omit it (with previewId absent) to parse and preview without writing.'}, 'bulkNote': {'type': 'string', 'description': "Step 2 only: one note (max 120 chars) prepended to every confirmed row's Notes, same as the app's 'Add note to all entries'."}, 'mimeType': {'enum': ['image/jpeg', 'image/png', 'image/webp', 'image/heic', 'image/heif', 'application/pdf'], 'type': 'string', 'description': 'MIME type of the file (default: image/jpeg)'}, 'rowEdits': {'type': 'array', 'items': {'type': 'object', 'required': ['index', 'fields'], 'properties': {'index': {'type': 'integer', 'description': 'Preview row index'}, 'fields': {'type': 'object', 'description': 'Only the user-approved income fields to replace on this staged row: date, source, amount, currency, category, paymentMethod, description, notes, reference, fees, taxCollected, or tag.', 'additionalProperties': True}}}, 'description': 'Step 2 only: user-approved corrections, at most 50 rows. Fields: date (ISO YYYY-MM-DD), source, amount, currency, category, paymentMethod, description, notes, reference, fees, taxCollected, tag.'}, 'previewId': {'type': 'string', 'description': 'Step 2 only: the previewId returned by the step-1 call.'}, 'photoBase64': {'type': 'string', 'description': 'Legacy fallback for MCP clients that send complete image/PDF bytes as base64. ChatGPT should use photo.'}, 'paymentMethod': {'type': 'string', 'description': 'Fallback payment rail for rows where the parser found none (Cash, Check, Bank transfer, Wallet app, Credit/Debit card, Payment processor, or Other).'}, 'keepBothIndexes': {'type': 'array', 'items': {'type': 'integer'}, 'description': "Step 2 only: preview indexes of duplicate-flagged rows the user explicitly wants to keep anyway (the app's 'Keep Both')."}, 'selectedIndexes': {'type': 'array', 'items': {'type': 'integer'}, 'description': 'Step 2 only: preview row indexes to write. Omit to write all staged rows.'}}}
Schéma de sortie
{'type': 'object', 'allOf': [{'if': {'required': ['preview'], 'properties': {'preview': {'const': True}}}, 'then': {'required': ['previewId', 'expiresAt', 'entryCount', 'entries', 'confirmationContract']}}, {'if': {'required': ['confirmed'], 'properties': {'confirmed': {'const': True}}}, 'then': {'required': ['previewId', 'written', 'deduped', 'failed', 'unattempted', 'total']}}], 'required': ['success', 'message'], 'properties': {'total': {'type': 'integer', 'minimum': 0}, 'failed': {'type': 'integer', 'minimum': 0}, 'deduped': {'type': 'integer', 'minimum': 0}, 'entries': {'type': 'array', 'items': {'type': 'object', 'properties': {'date': {'type': 'string', 'format': 'date'}, 'index': {'type': 'integer', 'minimum': 0}, 'payer': {'type': 'string'}, 'amount': {'type': 'number'}, 'currency': {'type': 'string'}, 'duplicate': {'type': 'boolean'}}, 'additionalProperties': True}}, 'message': {'type': 'string'}, 'preview': {'type': 'boolean'}, 'success': {'type': 'boolean'}, 'written': {'type': 'integer', 'minimum': 0}, 'warnings': {'type': 'array', 'items': {'type': 'string'}}, 'confirmed': {'type': 'boolean'}, 'expiresAt': {'type': 'string', 'format': 'date-time'}, 'previewId': {'type': 'string'}, 'duplicates': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'entryCount': {'type': 'integer', 'minimum': 0}, 'finalAnswer': {'type': 'string'}, 'unattempted': {'type': 'integer', 'minimum': 0}, 'rejectedRows': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'duplicateCount': {'type': 'integer', 'minimum': 0}, 'maxChatEntries': {'type': 'integer', 'minimum': 1}, 'refundRowCount': {'type': 'integer', 'minimum': 0}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewImportUrl': {'type': 'string'}, 'reviewIncomeUrl': {'type': 'string'}, 'tooLargeForChat': {'type': 'boolean'}, 'expiresInMinutes': {'type': 'integer', 'minimum': 1}, 'idempotentReplay': {'type': 'boolean'}, 'responseGuidance': {'type': 'string'}, 'totalsByCurrency': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'projectionTruncated': {'type': 'boolean'}, 'confirmationContract': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['distance', 'purpose'], 'properties': {'tag': {'type': 'string', 'description': 'Tag for client/project attribution (optional)'}, 'city': {'type': 'string', 'description': 'City (optional)'}, 'date': {'type': 'string', 'format': 'date', 'description': 'Trip date (YYYY-MM-DD). Defaults to today.'}, 'notes': {'type': 'string', 'description': 'Optional user-supplied context stored with the mileage entry.'}, 'purpose': {'type': 'string', 'description': "Business purpose / description of the trip (e.g., 'Client meeting at 1234 Main St')"}, 'category': {'type': 'string', 'description': "Override the user's default mileage category (optional)"}, 'distance': {'type': 'number', 'description': "Distance traveled in the user's configured unit (miles or km)"}, 'roundTrip': {'type': 'boolean', 'default': False, 'description': 'If true, doubles the distance (return trip)'}, 'destination': {'type': 'string', 'description': 'Destination address or location (optional)'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'message'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'settings': {'type': 'object', 'properties': {'unit': {'type': 'string'}, 'allowancePerUnit': {'type': 'number'}}, 'additionalProperties': True}, 'rowNumber': {'type': 'integer', 'minimum': 1}, 'finalAnswer': {'type': 'string'}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'responseGuidance': {'type': 'string'}, 'reviewExpensesUrl': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['reportId', 'userRequest'], 'properties': {'reportId': {'type': 'string', 'description': 'Report ID to check'}, 'userRequest': {'type': 'string', 'description': "The user's exact request explicitly asking for compliance, policy, audit, substantiation, or business-purpose analysis. Do not paraphrase or invent intent."}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['feature'], 'properties': {'feature': {'type': 'string', 'description': "Feature or integration to check (e.g., 'Xero', 'mileage tracking', 'Plaid')"}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': "Deductibility question (e.g., 'is Uber tax deductible', 'home office write-off rules')"}, 'category': {'type': 'string'}, 'merchant': {'type': 'string'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['operationId'], 'properties': {'undo': {'type': 'boolean', 'description': 'Undo a completed correction within its Undo window.'}, 'change': {'type': 'object', 'oneOf': [{'required': ['category'], 'properties': {'type': {'const': 'category'}}}, {'required': ['businessPurpose'], 'properties': {'type': {'const': 'businessPurpose'}}}, {'required': ['attendees'], 'properties': {'type': {'const': 'attendees'}}}], 'required': ['type'], 'properties': {'type': {'enum': ['category', 'businessPurpose', 'attendees'], 'type': 'string', 'description': 'The one correction kind to apply to every exact selected expense.'}, 'category': {'type': 'string', 'description': 'Configured expense category to apply when type is category.'}, 'attendees': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 25, 'minItems': 1, 'description': 'Attendee names explicitly supplied by the user when type is attendees; never infer names.'}, 'attendeeMode': {'enum': ['add', 'replace'], 'type': 'string', 'description': 'Use add unless the user explicitly asks to replace existing attendees.'}, 'businessPurpose': {'type': 'string', 'description': 'User-supplied business purpose to apply when type is businessPurpose.'}}, 'description': 'Exactly one correction. The selected type determines which matching value field is required.', 'additionalProperties': False}, 'status': {'type': 'boolean', 'description': 'Read operation status using operationId.'}, 'confirm': {'type': 'boolean', 'description': 'Omit/false for preview; true only after explicit approval.'}, 'selection': {'type': 'object', 'required': ['items'], 'properties': {'items': {'type': 'array', 'items': {'type': 'object', 'required': ['receiptId'], 'properties': {'expected': {'type': 'object', 'properties': {'notes': {'type': 'string', 'description': 'Current structured Notes value observed before preview for conflict detection.'}, 'category': {'type': 'string', 'description': 'Current category observed before preview for conflict detection.'}}, 'description': 'Optional optimistic-concurrency values copied from the search result.', 'additionalProperties': False}, 'receiptId': {'type': 'string', 'description': 'Exact full expenseId/Column-Q receipt identity from search_expenses.'}}, 'additionalProperties': False}, 'maxItems': 100, 'minItems': 1, 'description': 'One exact receipt identity per selected expense; never broaden this list after preview.'}}, 'description': 'Exact expenses returned by search_expenses and approved for this bounded correction.', 'additionalProperties': False}, 'operationId': {'type': 'string', 'pattern': '^expense-bulk:[a-zA-Z0-9_-]{8,100}$', 'description': 'Stable idempotency key generated once for preview and reused unchanged.'}}, 'additionalProperties': False}
Schéma de sortie
{'type': 'object', 'required': ['success', 'status'], 'properties': {'undo': {'type': 'object', 'additionalProperties': True}, 'change': {'type': 'object', 'additionalProperties': True}, 'status': {'type': 'string'}, 'message': {'type': 'string'}, 'preview': {'type': 'object', 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'manifest': {'type': 'object', 'additionalProperties': True}, 'finalAnswer': {'type': 'string'}, 'operationId': {'type': 'string'}, 'confirmation': {'type': 'object', 'additionalProperties': True}, 'responseGuidance': {'type': 'string'}, 'reviewExpensesUrl': {'type': 'string'}, 'requiresConfirmation': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['preparationId'], 'properties': {'confirmTax': {'type': 'boolean', 'description': 'True only after the user confirms the displayed tax label and rate.'}, 'operationId': {'type': 'string', 'description': 'Optional retry key. Reuse it after an uncertain response.'}, 'preparationId': {'type': 'string', 'description': 'Short-lived ID returned by prepare_client_invoice.'}}, 'additionalProperties': False}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'total': {'type': 'number'}, 'pdfUrl': {'type': ['string', 'null']}, 'status': {'type': 'string'}, 'docxUrl': {'type': ['string', 'null']}, 'dueDate': {'type': ['string', 'null'], 'format': 'date'}, 'success': {'type': 'boolean'}, 'currency': {'type': 'string'}, 'invoiceId': {'type': ['string', 'null']}, 'issueDate': {'type': ['string', 'null'], 'format': 'date'}, 'recovered': {'type': 'boolean'}, 'clientName': {'type': ['string', 'null']}, 'grandTotal': {'type': 'number'}, 'documentUrl': {'type': ['string', 'null']}, 'invoiceNumber': {'type': ['string', 'null']}, 'advanceApplied': {'type': 'number'}, 'sourceReportId': {'type': ['string', 'null']}, 'artifactWarning': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'tags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Existing ExpenseBot groups to include, such as a client, project, project code, property, or trip. Use list_tags first when uncertain.'}, 'title': {'type': 'string', 'description': 'Custom report title'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}, 'shareWith': {'type': 'array', 'items': {'type': 'string', 'format': 'email'}, 'description': 'Email addresses to share the report with'}, 'categories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional configured expense categories to include in the report.'}, 'excludedTags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Existing ExpenseBot groups to exclude from the report.'}, 'recipientRole': {'enum': ['reviewer', 'accountant'], 'type': 'string', 'default': 'reviewer', 'description': 'Access for every shareWith recipient. Use reviewer for one-report review, comments, approval, or change requests. Use accountant only when the user explicitly wants ongoing report management and accounting-software access.'}, 'excludePersonal': {'type': 'boolean', 'description': 'Exclude expenses whose Tag is Personal or whose Expense Category is Personal.'}, 'excludedCategories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Expense categories to exclude from the report.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'properties': {'link': {'type': 'string'}, 'title': {'type': 'string'}, 'reportId': {'type': 'string'}, 'appReportUrl': {'type': 'string'}, 'homeCurrency': {'type': 'string'}, 'receiptCount': {'type': 'integer', 'minimum': 0}, 'billClientUrl': {'type': 'string'}, 'appliedFilters': {'type': 'object', 'additionalProperties': True}, 'creationStatus': {'type': 'string'}, 'functionalTotal': {'type': 'number'}, 'personalExcludedCount': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'reportId': {'type': 'string'}, 'reportUrl': {'type': 'string'}, 'finalAnswer': {'type': 'string'}, 'nextActions': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'billClientUrl': {'type': 'string'}, 'creationStatus': {'type': 'string'}, 'responseGuidance': {'type': 'string'}, 'accountingSetupUrl': {'type': 'string'}, 'accountingHandoffUrls': {'type': 'object', 'additionalProperties': True}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['reportId'], 'properties': {'reportId': {'type': 'string', 'description': 'Report ID from list_reports'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'report', 'urls', 'expiresAt', 'availableInReport', 'notes'], 'properties': {'urls': {'type': 'object', 'required': ['view', 'pdf', 'report'], 'properties': {'pdf': {'type': 'string'}, 'view': {'type': 'string'}, 'report': {'type': 'string'}}, 'additionalProperties': True}, 'notes': {'type': 'string'}, 'report': {'type': 'object', 'required': ['title', 'spreadsheetId'], 'properties': {'id': {'type': 'string'}, 'title': {'type': 'string'}, 'status': {'type': 'string'}, 'spreadsheetId': {'type': 'string'}}, 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'expiresAt': {'type': 'string', 'format': 'date-time'}, 'availableInReport': {'type': 'array', 'items': {'type': 'string'}}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'pattern': '^(expense:\\d+|report:[A-Za-z0-9_-]+)$', 'description': "Item ID from a previous `search` or `list_reports` call. Format: 'expense:<row>' (integer row number) or 'report:<reportId>' (alphanumeric Firestore doc id, ~20 chars)."}}}
Schéma de sortie
{'type': 'object', 'required': ['id', 'title', 'text'], 'properties': {'id': {'type': 'string', 'description': 'Echoed back from the input'}, 'url': {'type': 'string', 'format': 'uri'}, 'text': {'type': 'string', 'description': 'Full text content for the AI to cite'}, 'title': {'type': 'string'}, 'metadata': {'type': 'object', 'additionalProperties': True}}}
Schéma d’entrée
{'type': 'object', 'required': ['operationId'], 'properties': {'undo': {'type': 'boolean', 'description': 'Undo a completed correction within its Undo window.'}, 'change': {'type': 'object', 'oneOf': [{'required': ['category'], 'properties': {'type': {'const': 'category'}}}, {'required': ['businessPurpose'], 'properties': {'type': {'const': 'businessPurpose'}}}, {'required': ['attendees'], 'properties': {'type': {'const': 'attendees'}}}], 'required': ['type'], 'properties': {'type': {'enum': ['category', 'businessPurpose', 'attendees'], 'type': 'string', 'description': 'The one correction kind to apply to every exact selected expense.'}, 'category': {'type': 'string', 'description': 'Configured expense category to apply when type is category.'}, 'attendees': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 25, 'minItems': 1, 'description': 'Attendee names explicitly supplied by the user when type is attendees; never infer names.'}, 'attendeeMode': {'enum': ['add', 'replace'], 'type': 'string', 'description': 'Use add unless the user explicitly asks to replace existing attendees.'}, 'businessPurpose': {'type': 'string', 'description': 'User-supplied business purpose to apply when type is businessPurpose.'}}, 'description': 'Exactly one correction. The selected type determines which matching value field is required.', 'additionalProperties': False}, 'status': {'type': 'boolean', 'description': 'Read operation status using operationId.'}, 'confirm': {'type': 'boolean', 'description': 'Omit/false for preview; true only after explicit approval.'}, 'selection': {'type': 'object', 'required': ['items'], 'properties': {'items': {'type': 'array', 'items': {'type': 'object', 'required': ['receiptId'], 'properties': {'expected': {'type': 'object', 'properties': {'notes': {'type': 'string', 'description': 'Current structured Notes value observed before preview for conflict detection.'}, 'category': {'type': 'string', 'description': 'Current category observed before preview for conflict detection.'}}, 'description': 'Optional optimistic-concurrency values copied from the search result.', 'additionalProperties': False}, 'receiptId': {'type': 'string', 'description': 'Exact full expenseId/Column-Q receipt identity from search_expenses.'}}, 'additionalProperties': False}, 'maxItems': 100, 'minItems': 1, 'description': 'One exact receipt identity per selected expense; never broaden this list after preview.'}}, 'description': 'Exact expenses returned by search_expenses and approved for this bounded correction.', 'additionalProperties': False}, 'operationId': {'type': 'string', 'pattern': '^expense-bulk:[a-zA-Z0-9_-]{8,100}$', 'description': 'Stable idempotency key generated once for preview and reused unchanged.'}}, 'additionalProperties': False}
Schéma de sortie
{'type': 'object', 'required': ['success', 'status'], 'properties': {'undo': {'type': 'object', 'additionalProperties': True}, 'change': {'type': 'object', 'additionalProperties': True}, 'status': {'type': 'string'}, 'message': {'type': 'string'}, 'preview': {'type': 'object', 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'manifest': {'type': 'object', 'additionalProperties': True}, 'finalAnswer': {'type': 'string'}, 'operationId': {'type': 'string'}, 'confirmation': {'type': 'object', 'additionalProperties': True}, 'responseGuidance': {'type': 'string'}, 'reviewExpensesUrl': {'type': 'string'}, 'requiresConfirmation': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['provider'], 'properties': {'provider': {'enum': ['zoho_books', 'quickbooks', 'xero', 'wave', 'freeagent'], 'type': 'string', 'description': 'Accounting destination provider. QuickBooks Online, Xero, Wave, FreeAgent (beta), or Zoho Books.'}, 'reportId': {'type': 'string', 'description': "Optional existing ExpenseBot report ID. When supplied, setupUrl opens this exact report and highlights the selected accounting provider's setup control."}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'description': 'Per-provider connection and rollout state.', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['provider', 'reportId'], 'properties': {'provider': {'enum': ['zoho_books', 'quickbooks', 'xero', 'wave', 'freeagent'], 'type': 'string', 'description': 'Accounting destination provider used for the prior posting attempt.'}, 'reportId': {'type': 'string', 'description': 'Exact ExpenseBot report ID from the prior proposal or posting attempt.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'clientName': {'type': 'string', 'description': 'Optional client name or canonical Client tag. Omit to list every open balance backed by a recorded client advance.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'balances': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'homeCurrency': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'invoiceId': {'type': 'string', 'description': 'Stable invoice ID from list_client_invoices. Required unless invoiceNumber is supplied.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}, 'invoiceNumber': {'type': 'string', 'description': 'Human invoice number when invoiceId is unavailable; it must identify one unique invoice.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'invoice': {'type': 'object', 'properties': {'pdfUrl': {'type': ['string', 'null']}, 'status': {'type': 'string', 'description': 'Stored status, e.g. "open", "paid", "void".'}, 'dueDate': {'type': ['string', 'null']}, 'currency': {'type': 'string'}, 'paidDate': {'type': ['string', 'null'], 'description': 'null until paid.'}, 'subtotal': {'type': 'number'}, 'clientTag': {'type': ['string', 'null']}, 'invoiceId': {'type': 'string', 'description': 'Durable invoice identity.'}, 'issueDate': {'type': ['string', 'null']}, 'reportUrl': {'type': ['string', 'null']}, 'taxAmount': {'type': 'number'}, 'balanceDue': {'type': 'number'}, 'clientName': {'type': ['string', 'null']}, 'grandTotal': {'type': 'number'}, 'paidAmount': {'type': ['number', 'null'], 'description': 'null until paid.'}, 'documentUrl': {'type': ['string', 'null']}, 'billClientUrl': {'type': ['string', 'null']}, 'displayStatus': {'enum': ['open', 'overdue', 'paid', 'void', 'superseded', 'needs_review'], 'type': 'string', 'description': 'Derived: overdue is computed from status + dueDate, not stored.'}, 'invoiceNumber': {'type': ['string', 'null']}, 'advanceApplied': {'type': 'number'}, 'deliveryStatus': {'type': 'string'}}, 'description': 'The invoice record. Absent only on the error branch (not-found), which never carries structuredContent.', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'limit': {'type': 'number', 'description': 'Maximum results to return (default 25, max 100).'}, 'dateRange': {'type': 'object', 'properties': {'endDate': {'type': 'string', 'format': 'date', 'description': 'Inclusive end date in YYYY-MM-DD format.'}, 'startDate': {'type': 'string', 'format': 'date', 'description': 'Inclusive start date in YYYY-MM-DD format.'}}, 'description': 'Optional open-ended or closed window to narrow results. Supply startDate, endDate, or both; supplied bounds are inclusive YYYY-MM-DD dates.', 'additionalProperties': False}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'credits': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'message': {'type': 'string'}, 'refunds': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': 'The analytics question to answer'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'description': 'Inline branch: computed analytics, or null when no spreadsheet / no data.', 'additionalProperties': True}, 'type': {'type': 'string', 'description': 'Async branch only: "analytics_pending" â\x80\x94 poll pollEndpoint or call poll_analytics with jobId.'}, 'jobId': {'type': 'string', 'description': 'Async branch only.'}, 'message': {'type': 'string', 'description': 'Human-readable narrative (both branches).'}, 'success': {'type': 'boolean', 'description': 'Async branch only.'}, 'response': {'type': 'string', 'description': 'Chat alias of message.'}, 'pollEndpoint': {'type': 'string', 'description': 'Async branch only.'}, 'pollInterval': {'type': 'number', 'description': 'Async branch only: milliseconds.'}, 'estimatedTime': {'type': 'number', 'description': 'Async branch only: seconds.'}}, 'description': "Two branches. Async: type='analytics_pending' with jobId â\x80\x94 poll poll_analytics until complete. Inline: message + data with the computed analytics (data may be null when there is no spreadsheet or no data yet). success is present only on the async branch.", 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'expenseId': {'type': 'string', 'description': 'Exact full ExpenseBot Receipt ID from Column Q'}, 'rowNumber': {'type': 'integer', 'minimum': 2, 'description': '1-indexed sheet row (row 1 is headers, so â\x89¥ 2)'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'expense': {'type': 'object', 'description': 'The expense record.', 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'rowNumber': {'type': 'integer', 'description': 'Resolved sheet row for the expense.'}, 'reviewExpenseUrl': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'limit': {'type': 'number', 'description': 'Max parent expenses to return (default 25, max 100).'}, 'dateRange': {'type': 'object', 'properties': {'endDate': {'type': 'string', 'format': 'date', 'description': 'Inclusive end date in YYYY-MM-DD format.'}, 'startDate': {'type': 'string', 'format': 'date', 'description': 'Inclusive start date in YYYY-MM-DD format.'}}, 'description': 'Optional open-ended or closed window to search for split expenses. Supply startDate, endDate, or both; supplied bounds are inclusive YYYY-MM-DD dates.', 'additionalProperties': False}, 'onlySplit': {'type': 'boolean', 'description': 'Return only expenses with active splits (default true). Set false to inspect an unsplit Receipt ID.'}, 'receiptId': {'type': 'string', 'description': 'Optional Receipt ID for one expense.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'splits': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'query': {'type': 'string', 'description': "Natural language income question (e.g., 'income YTD by source', 'rental income last month')"}, 'groupBy': {'enum': ['source', 'category', 'month', 'paymentMethod', 'tag'], 'type': 'string', 'description': 'How to group the breakdown'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}, 'incomeTagPrefix': {'type': 'string', 'description': "Optional tag-prefix shortcut (e.g., 'Prop â\x80\x93' for rental income, 'Client â\x80\x93' for client billings, 'Wedding â\x80\x93' for events). When set, the tool filters to income rows tagged with this prefix."}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'description': 'Inline branch: computed analytics, or null when no spreadsheet / no data.', 'additionalProperties': True}, 'type': {'type': 'string', 'description': 'Async branch only: "analytics_pending" â\x80\x94 poll pollEndpoint or call poll_analytics with jobId.'}, 'jobId': {'type': 'string', 'description': 'Async branch only.'}, 'message': {'type': 'string', 'description': 'Human-readable narrative (both branches).'}, 'success': {'type': 'boolean', 'description': 'Async branch only.'}, 'response': {'type': 'string', 'description': 'Chat alias of message.'}, 'pollEndpoint': {'type': 'string', 'description': 'Async branch only.'}, 'pollInterval': {'type': 'number', 'description': 'Async branch only: milliseconds.'}, 'estimatedTime': {'type': 'number', 'description': 'Async branch only: seconds.'}}, 'description': "Two branches. Async: type='analytics_pending' with jobId â\x80\x94 poll poll_analytics until complete. Inline: message + data with the computed analytics (data may be null when there is no spreadsheet or no data yet). success is present only on the async branch.", 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'submissionId': {'type': 'string', 'description': 'Exact submissionId returned by submit_receipt. Strongly preferred because it binds the result to this upload instead of an earlier receipt.'}, 'withinSeconds': {'type': 'integer', 'default': 600, 'maximum': 3600, 'minimum': 30, 'description': 'Fallback lookback window when submissionId is unavailable (30-3600 seconds; default 600).'}}}
Schéma de sortie
{'type': 'object', 'allOf': [{'if': {'required': ['found'], 'properties': {'found': {'const': True}}}, 'then': {'required': ['verdict', 'counts', 'receipts', 'submissionId', 'spreadsheetUrl', 'reviewExpensesUrl', 'data', 'timestamp']}}], 'required': ['success', 'found', 'message'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'found': {'type': 'boolean'}, 'state': {'type': 'string', 'const': 'processing', 'description': 'Present on pending polls for a specific submission.'}, 'counts': {'type': 'object', 'required': ['submitted', 'added', 'duplicates', 'skipped', 'errors'], 'properties': {'added': {'type': 'integer', 'minimum': 0}, 'errors': {'type': 'integer', 'minimum': 0}, 'skipped': {'type': 'integer', 'minimum': 0}, 'submitted': {'type': 'integer', 'minimum': 0}, 'duplicates': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean', 'const': True}, 'verdict': {'enum': ['added', 'duplicate', 'skipped', 'errored', 'mixed', 'unknown'], 'type': 'string', 'description': 'Terminal branch only.'}, 'receipts': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'timestamp': {'type': ['string', 'null'], 'format': 'date-time'}, 'submissionId': {'type': ['string', 'null']}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewExpensesUrl': {'type': 'string'}}, 'description': 'found:false means processing is still pending; found:true is a terminal result.', 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'query': {'type': 'string', 'description': "Natural language mileage question (e.g., 'mileage this year', 'miles driven for Acme client')"}, 'groupBy': {'enum': ['month', 'tag', 'purpose', 'category'], 'type': 'string', 'description': 'How to group the breakdown'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean', 'description': 'Present only on the error branch (out of scope) / async path.'}}, 'description': 'Success returns message + data with the computed summary; success is not emitted on the inline analytics path.', 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'period': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}$', 'description': 'Calendar month in YYYY-MM format. Defaults to the last completed month.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'query': {'type': 'string', 'description': 'Natural language per-tag P&L question'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}, 'tagPrefix': {'type': 'string', 'description': "Optional prefix to limit which tags are bucketed (e.g., 'Prop â\x80\x93' for properties only, 'Client â\x80\x93' for clients only). When omitted, all tags are included."}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'description': 'Inline branch: computed analytics, or null when no spreadsheet / no data.', 'additionalProperties': True}, 'type': {'type': 'string', 'description': 'Async branch only: "analytics_pending" â\x80\x94 poll pollEndpoint or call poll_analytics with jobId.'}, 'jobId': {'type': 'string', 'description': 'Async branch only.'}, 'message': {'type': 'string', 'description': 'Human-readable narrative (both branches).'}, 'success': {'type': 'boolean', 'description': 'Async branch only.'}, 'response': {'type': 'string', 'description': 'Chat alias of message.'}, 'pollEndpoint': {'type': 'string', 'description': 'Async branch only.'}, 'pollInterval': {'type': 'number', 'description': 'Async branch only: milliseconds.'}, 'estimatedTime': {'type': 'number', 'description': 'Async branch only: seconds.'}}, 'description': "Two branches. Async: type='analytics_pending' with jobId â\x80\x94 poll poll_analytics until complete. Inline: message + data with the computed analytics (data may be null when there is no spreadsheet or no data yet). success is present only on the async branch.", 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'query': {'type': 'string', 'description': "Natural language P&L question (e.g., 'P&L for Q1 2025', 'am I profitable')"}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'description': 'Inline branch: computed analytics, or null when no spreadsheet / no data.', 'additionalProperties': True}, 'type': {'type': 'string', 'description': 'Async branch only: "analytics_pending" â\x80\x94 poll pollEndpoint or call poll_analytics with jobId.'}, 'jobId': {'type': 'string', 'description': 'Async branch only.'}, 'message': {'type': 'string', 'description': 'Human-readable narrative (both branches).'}, 'success': {'type': 'boolean', 'description': 'Async branch only.'}, 'response': {'type': 'string', 'description': 'Chat alias of message.'}, 'pollEndpoint': {'type': 'string', 'description': 'Async branch only.'}, 'pollInterval': {'type': 'number', 'description': 'Async branch only: milliseconds.'}, 'estimatedTime': {'type': 'number', 'description': 'Async branch only: seconds.'}}, 'description': "Two branches. Async: type='analytics_pending' with jobId â\x80\x94 poll poll_analytics until complete. Inline: message + data with the computed analytics (data may be null when there is no spreadsheet or no data yet). success is present only on the async branch.", 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 20, 'maximum': 100, 'minimum': 1}, 'actionId': {'type': 'string', 'description': 'Optional: filter to a single tool/action name'}, 'sinceDays': {'type': 'integer', 'default': 7, 'description': 'Only show actions from the last N days (default 7)'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'count', 'actions'], 'properties': {'count': {'type': 'integer'}, 'actions': {'type': 'array', 'items': {'type': 'object', 'properties': {'success': {'type': 'boolean'}, 'actionId': {'type': 'string'}, 'timestamp': {'type': 'string'}, 'durationMs': {'type': 'number'}}, 'additionalProperties': True}}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['reportId', 'userRequest'], 'properties': {'reportId': {'type': 'string', 'description': 'The report/spreadsheet ID'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}, 'userRequest': {'type': 'string', 'description': "The user's exact request asking to inspect this report. Do not paraphrase or invent diagnostic intent."}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'report'], 'properties': {'report': {'type': 'object', 'description': 'The full stored report record.', 'additionalProperties': True}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'lock': {'type': 'object', 'description': 'Scan-lock state (active, startedAt, ageSeconds, dispatchComplete, pendingProcessingCount).', 'additionalProperties': True}, 'status': {'type': ['string', 'null'], 'description': 'Scan lifecycle state.'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'latestScan': {'type': ['object', 'null'], 'description': 'Most recent scan outcome (success, emailsFound, emailsTagged, timestamp).', 'additionalProperties': True}, 'gmailScanUrl': {'type': ['string', 'null']}, 'scanInProgress': {'type': 'boolean'}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewExpensesUrl': {'type': ['string', 'null']}}, 'description': 'Authoritative live scan state. Fields may sit at the top level or under data depending on the branch; nothing beyond success is guaranteed, so treat each as optional.', 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'query': {'type': 'string', 'description': "Natural language question (e.g., 'how much did I spend in March', 'top merchants this quarter')"}, 'metric': {'enum': ['total', 'count', 'average'], 'type': 'string'}, 'groupBy': {'enum': ['category', 'merchant', 'month', 'tag', 'source', 'paymentMethod'], 'type': 'string'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}, 'categories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional configured expense categories to include in the summary.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'description': 'Inline branch: computed analytics, or null when no spreadsheet / no data.', 'additionalProperties': True}, 'type': {'type': 'string', 'description': 'Async branch only: "analytics_pending" â\x80\x94 poll pollEndpoint or call poll_analytics with jobId.'}, 'jobId': {'type': 'string', 'description': 'Async branch only.'}, 'message': {'type': 'string', 'description': 'Human-readable narrative (both branches).'}, 'success': {'type': 'boolean', 'description': 'Async branch only.'}, 'response': {'type': 'string', 'description': 'Chat alias of message.'}, 'pollEndpoint': {'type': 'string', 'description': 'Async branch only.'}, 'pollInterval': {'type': 'number', 'description': 'Async branch only: milliseconds.'}, 'estimatedTime': {'type': 'number', 'description': 'Async branch only: seconds.'}}, 'description': "Two branches. Async: type='analytics_pending' with jobId â\x80\x94 poll poll_analytics until complete. Inline: message + data with the computed analytics (data may be null when there is no spreadsheet or no data yet). success is present only on the async branch.", 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'spreadsheetId', 'spreadsheetUrl', 'reviewExpensesUrl', 'reviewIncomeUrl', 'gmailScanUrl', 'gmailActionNeededUrl', 'reportsUrl', 'dashboardUrl', 'data', 'message'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean', 'const': True}, 'reportsUrl': {'type': 'string'}, 'dashboardUrl': {'type': 'string'}, 'gmailScanUrl': {'type': 'string'}, 'spreadsheetId': {'type': 'string', 'minLength': 1}, 'spreadsheetUrl': {'type': 'string'}, 'reviewIncomeUrl': {'type': 'string'}, 'reviewExpensesUrl': {'type': 'string'}, 'gmailActionNeededUrl': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'focus': {'enum': ['recurring', 'duplicates', 'price_increases', 'trial_conversions', 'all'], 'type': 'string', 'description': 'Narrow the audit to a single category (default: all)'}, 'query': {'type': 'string', 'description': "Natural language subscription question (e.g., 'find duplicate subscriptions', 'price increases this year')"}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}}}
Schéma de sortie
{'type': 'object', 'required': [], 'properties': {'data': {'type': ['object', 'null'], 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean', 'description': 'Present only on the error branch (out of scope) / async path.'}}, 'description': 'Success returns message + data with the computed summary; success is not emitted on the inline analytics path.', 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'maximum': 5, 'minimum': 1, 'description': 'Maximum high-confidence proposals to return (default 3).'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}, 'additionalProperties': False}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'count': {'type': 'integer'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'proposals': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Read-only trip proposals; accepting one continues through group_expenses.'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['operationId'], 'properties': {'undo': {'type': 'boolean', 'description': 'Undo a completed grouping within its undo window.'}, 'group': {'type': 'object', 'required': ['kind', 'name'], 'properties': {'kind': {'enum': ['client', 'project', 'trip', 'job', 'group'], 'type': 'string', 'description': 'How to label the destination in user-facing confirmation text.'}, 'name': {'type': 'string', 'description': "The group name in the user's own words."}}, 'description': 'The user-named destination group to apply to every eligible selected expense.', 'additionalProperties': False}, 'status': {'type': 'boolean', 'description': 'Read operation status using operationId.'}, 'confirm': {'type': 'boolean', 'description': 'Omit/false for preview; true only after explicit approval.'}, 'selection': {'type': 'object', 'required': ['items'], 'properties': {'items': {'type': 'array', 'items': {'type': 'object', 'required': ['receiptId'], 'properties': {'expected': {'type': 'object', 'properties': {'tag': {'type': 'string', 'description': 'Current group/tag value observed before preview; an empty string means ungrouped.'}}, 'description': 'Optional current state copied from search results for conflict detection.', 'additionalProperties': False}, 'receiptId': {'type': 'string', 'description': 'Exact full expenseId/Column-Q receipt identity.'}}, 'additionalProperties': False}, 'maxItems': 500, 'minItems': 1, 'description': 'One exact receipt identity per selected expense; never broaden this list after preview.'}}, 'description': 'Exact expenses returned by search_expenses and approved for this bounded operation.', 'additionalProperties': False}, 'operationId': {'type': 'string', 'pattern': '^expense-bulk:[a-zA-Z0-9_-]{8,100}$', 'description': 'Stable idempotency key generated once for the preview and reused unchanged.'}, 'reportTitle': {'type': 'string', 'description': 'Optional title when createReport is true; otherwise ExpenseBot derives one from the group.'}, 'createReport': {'type': 'boolean', 'description': 'Create a report from the exact eligible grouped expenses.'}, 'excludedTags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Existing groups to exclude before preview and grouping.'}, 'approveNewGroup': {'type': 'boolean', 'description': 'True only when the preview says a new group is required.'}, 'excludePersonal': {'type': 'boolean', 'description': 'Exclude Personal-tagged and Personal-category expenses from both grouping and the exact report.'}, 'excludedCategories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Expense categories to exclude before preview and grouping.'}}, 'additionalProperties': False}
Schéma de sortie
{'type': 'object', 'required': ['success', 'status'], 'properties': {'undo': {'type': 'object', 'additionalProperties': True}, 'group': {'type': 'object', 'additionalProperties': True}, 'report': {'type': 'object', 'additionalProperties': True}, 'status': {'type': 'string'}, 'message': {'type': 'string'}, 'preview': {'type': 'object', 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'manifest': {'type': 'object', 'additionalProperties': True}, 'candidates': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'exclusions': {'type': 'object', 'additionalProperties': True}, 'reportsUrl': {'type': 'string'}, 'finalAnswer': {'type': 'string'}, 'operationId': {'type': 'string'}, 'confirmation': {'type': 'object', 'additionalProperties': True}, 'suggestedTag': {'type': 'string'}, 'creationStatus': {'type': 'string'}, 'responseGuidance': {'type': 'string'}, 'reviewExpensesUrl': {'type': 'string'}, 'requiresConfirmation': {'type': 'boolean'}, 'requiresNewGroupApproval': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'categories'], 'properties': {'success': {'type': 'boolean'}, 'categories': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Expense categories for the user.'}, 'billingAccounts': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Billing/card accounts, when configured.'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'limit': {'type': 'number', 'description': 'Max invoices to return (default 25, max 100).'}, 'status': {'enum': ['active', 'open', 'overdue', 'needs_review', 'paid', 'void', 'superseded', 'all'], 'type': 'string', 'description': 'Filter by invoice status (default active/outstanding).'}, 'clientName': {'type': 'string', 'description': 'Optional: exact client name (case-insensitive).'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'invoices'], 'properties': {'success': {'type': 'boolean'}, 'invoices': {'type': 'array', 'items': {'type': 'object', 'properties': {'total': {'type': 'number'}, 'status': {'type': 'string'}, 'currency': {'type': 'string'}, 'invoiceId': {'type': 'string'}, 'issueDate': {'type': ['string', 'null']}, 'clientName': {'type': ['string', 'null']}, 'grandTotal': {'type': 'number'}, 'displayStatus': {'enum': ['open', 'overdue', 'paid', 'void', 'superseded', 'needs_review'], 'type': 'string'}, 'invoiceNumber': {'type': ['string', 'null']}, 'advanceApplied': {'type': 'number'}}, 'additionalProperties': True}}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'categories'], 'properties': {'notes': {'type': 'string'}, 'legacy': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Deprecated income categories still accepted on read.'}, 'success': {'type': 'boolean'}, 'categories': {'type': 'array', 'items': {'type': 'string'}}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'page': {'type': 'integer', 'default': 1, 'description': 'One-based results page to return.'}, 'limit': {'type': 'integer', 'default': 20, 'description': 'Maximum reports to return on this page.'}, 'filter': {'enum': ['All', 'Draft', 'Submitted', 'Shared'], 'type': 'string', 'default': 'All', 'description': 'Optional report-status filter; All returns every authorized status.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'creationStatus'], 'properties': {'page': {'type': 'integer'}, 'limit': {'type': 'integer'}, 'filter': {'type': 'string'}, 'reports': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Present when the user has reports.'}, 'success': {'type': 'boolean'}, 'creationStatus': {'type': 'string', 'description': 'Provenance of the listing, e.g. "existing_only".'}, 'responseGuidance': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'tags'], 'properties': {'tags': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Client / project / trip groups (Column K values).'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['invoiceId', 'paidDate'], 'properties': {'paidVia': {'type': 'string', 'description': 'Optional payment method or source, such as bank transfer or check.'}, 'paidDate': {'type': 'string', 'format': 'date', 'description': 'Calendar-valid payment date in YYYY-MM-DD format.'}, 'invoiceId': {'type': 'string', 'description': 'Stable invoice ID from list_client_invoices.'}, 'paidAmount': {'type': 'number', 'minimum': 0, 'description': 'Optional amount received.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'invoiceId', 'status', 'paidDate', 'paidAmount', 'paidVia', 'incomeRowCreated', 'message'], 'properties': {'status': {'type': 'string', 'const': 'paid'}, 'message': {'type': 'string'}, 'paidVia': {'type': 'string'}, 'success': {'type': 'boolean'}, 'paidDate': {'type': 'string', 'format': 'date'}, 'invoiceId': {'type': 'string'}, 'paidAmount': {'type': ['number', 'null']}, 'invoiceNumber': {'type': ['string', 'null']}, 'incomeRowCreated': {'type': 'boolean', 'const': False}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['text'], 'properties': {'text': {'type': 'string', 'description': 'Natural language expense (e.g., "Coffee at Starbucks $6.50 yesterday")'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'expenses', 'validationErrors', 'categoryNames'], 'properties': {'success': {'type': 'boolean'}, 'expenses': {'type': 'array', 'items': {'type': 'object', 'properties': {'date': {'type': 'string', 'format': 'date'}, 'amount': {'type': 'number'}, 'category': {'type': 'string'}, 'currency': {'type': 'string'}, 'merchant': {'type': 'string'}}, 'additionalProperties': True}}, 'categoryNames': {'type': 'array', 'items': {'type': 'string'}}, 'validationErrors': {'type': 'array', 'items': {}}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['reportId', 'clientName', 'issueDate'], 'properties': {'taxPct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': 'Tax percentage applied after markup and custom line items; use 0 for no tax.'}, 'reportId': {'type': 'string', 'description': 'Saved ExpenseBot report ID to invoice.'}, 'taxLabel': {'type': 'string', 'description': 'Tax label such as HST, GST, or VAT.'}, 'issueDate': {'type': 'string', 'format': 'date', 'description': 'Calendar-valid invoice date in YYYY-MM-DD format.'}, 'markupPct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': 'Markup applied only to rebilled expense rows.'}, 'clientName': {'type': 'string', 'description': 'Full client or business name shown on the invoice.'}, 'receiptIds': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional exact report receipt IDs. Defaults to every current report expense.'}, 'billToEmail': {'type': 'string', 'description': 'Optional client email printed on the invoice. This does not send email.'}, 'paymentTerms': {'enum': ['due_on_receipt', 'net7', 'net14', 'net15', 'net30', 'net45', 'net60'], 'type': 'string', 'description': "Invoice due terms. Defaults to the client's billing profile or net30."}, 'clientAddress': {'type': 'string', 'description': "Optional billing address printed in the invoice's Bill To section."}, 'invoiceNumber': {'type': 'string', 'description': 'Optional custom invoice number. ExpenseBot allocates one when omitted.'}, 'advanceApplied': {'type': 'number', 'minimum': 0, 'description': 'Verified client advance to apply against this invoice.'}, 'customLineItems': {'type': 'array', 'items': {'type': 'object', 'required': ['description', 'amount'], 'properties': {'amount': {'type': 'number', 'description': 'Positive amount for this fee or service line in the invoice currency.', 'exclusiveMinimum': 0}, 'description': {'type': 'string', 'description': 'User-approved fee or service description shown on the invoice.'}}}, 'maxItems': 25, 'description': 'Optional fee/service lines. They are taxed but never marked up.'}, 'mentionSupportingReceipts': {'type': 'boolean', 'description': 'When true, note on the invoice that supporting receipts are available.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'preparationId', 'expiresAt', 'preview'], 'properties': {'preview': {'type': 'object', 'properties': {'taxPct': {'type': 'number'}, 'dueDate': {'type': 'string', 'format': 'date'}, 'currency': {'type': 'string'}, 'reportId': {'type': 'string'}, 'subtotal': {'type': 'number'}, 'taxLabel': {'type': 'string'}, 'clientTag': {'type': 'string'}, 'issueDate': {'type': 'string', 'format': 'date'}, 'markupPct': {'type': 'number'}, 'taxAmount': {'type': 'number'}, 'balanceDue': {'type': 'number'}, 'clientName': {'type': 'string'}, 'grandTotal': {'type': 'number'}, 'reportTitle': {'type': 'string'}, 'expenseCount': {'type': 'integer', 'minimum': 0}, 'markupAmount': {'type': 'number'}, 'paymentTerms': {'type': 'string'}, 'invoiceNumber': {'type': 'string'}, 'advanceApplied': {'type': 'number'}, 'customLineCount': {'type': 'integer', 'minimum': 0}, 'hasTaxRegistration': {'type': 'boolean'}, 'taxConfirmationRequired': {'type': 'boolean'}}, 'additionalProperties': True}, 'success': {'type': 'boolean'}, 'expiresAt': {'type': 'string', 'format': 'date-time'}, 'preparationId': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['emailIds'], 'properties': {'emailIds': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Gmail message IDs to process as receipts'}, 'accountEmail': {'type': 'string', 'description': 'Optional: which Gmail account to use (for users with multiple linked accounts)'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'message'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'error': {'type': 'string'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'emailCount': {'type': 'integer', 'minimum': 0}, 'processInfo': {'type': 'object', 'properties': {'status': {'type': 'string'}, 'sessionId': {'type': 'string'}, 'processingCompleted': {'type': 'boolean'}}, 'additionalProperties': True}, 'submissionId': {'type': 'string'}, 'processedItems': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewExpensesUrl': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['packageName'], 'properties': {'packageName': {'type': 'string', 'description': 'Exact accounting package requested by the user.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'duplicate', 'packageName', 'message'], 'properties': {'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'duplicate': {'type': 'boolean'}, 'packageName': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'endDate': {'type': 'string', 'format': 'date', 'description': 'Optional: explicit end date (YYYY-MM-DD)'}, 'startDate': {'type': 'string', 'format': 'date', 'description': 'Optional: explicit start date (YYYY-MM-DD) instead of lookbackDays'}, 'accountEmail': {'type': 'string', 'description': 'Optional: which Gmail account to scan'}, 'lookbackDays': {'type': 'integer', 'default': 60, 'description': 'How many days back to scan (default 60, max depends on subscription)'}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'additionalProperties': True}, 'status': {'type': 'string'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, '_metadata': {'type': 'object', 'additionalProperties': True}, 'sessionId': {'type': 'string'}, 'orchestrated': {'type': 'boolean'}, 'submissionId': {'type': 'string'}, 'scanInProgress': {'type': 'boolean'}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewExpensesUrl': {'type': ['string', 'null']}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['years'], 'properties': {'years': {'type': 'array', 'items': {'type': 'number'}, 'description': 'Completed prior years to scan, e.g. [2020, 2021]. Max 10.'}, 'accountEmail': {'type': 'string', 'description': 'Optional: which connected Gmail inbox to scan (multi-inbox users). Defaults to the primary.'}, 'confirmStart': {'type': 'boolean', 'description': 'Omit or false = preview only (no scan starts). Must be exactly true to start scanning.'}}}
Schéma de sortie
{'type': 'object', 'allOf': [{'if': {'required': ['preview'], 'properties': {'preview': {'const': True}}}, 'then': {'required': ['account', 'eligible', 'alreadyScanned', 'notEligible']}}], 'required': ['success', 'message'], 'properties': {'account': {'type': 'string'}, 'message': {'type': 'string'}, 'preview': {'type': 'boolean'}, 'success': {'type': 'boolean'}, 'eligible': {'type': 'array', 'items': {'type': 'integer'}}, 'gmailUrl': {'type': 'string'}, 'scanning': {'type': 'array', 'items': {'type': 'integer'}}, 'notEligible': {'type': 'array', 'items': {'type': 'object', 'required': ['year', 'reason'], 'properties': {'code': {'type': 'string'}, 'year': {'type': 'integer'}, 'reason': {'type': 'string'}}, 'additionalProperties': True}}, 'queuedYears': {'type': 'array', 'items': {'type': 'integer'}}, 'startedYear': {'type': ['integer', 'null']}, 'alreadyQueued': {'type': 'array', 'items': {'type': 'integer'}}, 'alreadyScanned': {'type': 'array', 'items': {'type': 'integer'}}, 'archiveThroughYear': {'type': 'integer'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': "Natural language search (e.g., 'Uber rides in March', 'Q1 client report', 'mileage Acme')"}}}
Schéma de sortie
{'type': 'object', 'required': ['results'], 'properties': {'results': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'title'], 'properties': {'id': {'type': 'string', 'description': 'Pass to `fetch` to retrieve full content'}, 'url': {'type': 'string', 'format': 'uri'}, 'title': {'type': 'string'}}}}}}
Schéma d’entrée
{'type': 'object', 'properties': {'tags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Filter by tags'}, 'limit': {'type': 'integer', 'default': 20, 'maximum': 50, 'minimum': 1, 'description': 'Results per page (default 20, maximum 50)'}, 'query': {'type': 'string', 'description': "Optional natural-language recall over the user's existing expense fields (merchant, city/location, Notes including receipt items, delivery source, payer, and Business purpose, Tag, category). Deterministic case-insensitive matching â\x80\x94 no embeddings or model classifiers. Combine with structured filters using AND semantics. Examples: 'Tribeca restaurant', 'Bodewell project hardware store', 'client dinner note'."}, 'cursor': {'type': 'string', 'description': 'Opaque nextCursor returned by the previous search_expenses page. Reuse the same filters; never construct or edit this value.'}, 'dateRange': {'oneOf': [{'type': 'object', 'title': 'Specific month', 'required': ['type', 'month', 'year'], 'properties': {'type': {'type': 'string', 'const': 'month'}, 'year': {'type': 'integer', 'description': '4-digit year (e.g., 2026)'}, 'month': {'type': 'string', 'description': "Month name or 1-12 (e.g., 'March' or '3')"}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Quarter of a year', 'required': ['type', 'quarter', 'year'], 'properties': {'type': {'type': 'string', 'const': 'quarter'}, 'year': {'type': 'integer'}, 'quarter': {'type': 'integer', 'maximum': 4, 'minimum': 1}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Full year', 'required': ['type', 'year'], 'properties': {'type': {'type': 'string', 'const': 'year'}, 'year': {'type': 'integer'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Specific date range', 'required': ['type', 'start', 'end'], 'properties': {'end': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}, 'type': {'type': 'string', 'const': 'specific'}, 'start': {'type': 'string', 'format': 'date', 'description': 'ISO date YYYY-MM-DD (inclusive)'}}, 'additionalProperties': False}, {'type': 'object', 'title': 'Relative natural-language range', 'required': ['type', 'value'], 'properties': {'type': {'type': 'string', 'const': 'relative'}, 'value': {'type': 'string', 'description': "Relative range phrase, e.g., 'last month', 'YTD', 'this quarter', 'last 7 days'"}}, 'additionalProperties': False}], 'description': "Time period filter. Use exactly one variant â\x80\x94 pick the shape that matches the user's phrasing."}, 'maxAmount': {'type': 'number', 'description': 'Maximum expense amount'}, 'merchants': {'type': 'array', 'items': {'type': 'string'}, 'description': "Filter by merchant names (e.g., ['Uber', 'Starbucks'])"}, 'minAmount': {'type': 'number', 'description': 'Minimum expense amount'}, 'categories': {'type': 'array', 'items': {'type': 'string'}, 'description': "Filter by expense categories (e.g., ['Travel', 'Meals'])"}, 'hasReceipt': {'type': 'boolean', 'description': 'When true, return only expenses with a receipt link. When false, return only expenses without one.'}, 'clientEmail': {'type': 'string', 'format': 'email', 'description': 'Client account email. Accountants may use this only for an accepted ExpenseBot client.'}}}
Schéma de sortie
{'type': 'object', 'required': ['expenses', 'count', 'total'], 'properties': {'count': {'type': 'integer', 'description': 'Rows matched by the filters.'}, 'total': {'type': 'number', 'description': 'Sum of the matched set in home currency.'}, 'hasMore': {'type': 'boolean'}, 'message': {'type': 'string'}, 'expenses': {'type': 'array', 'items': {'type': 'object', 'required': ['expenseId', 'date', 'amount', 'tag', 'updateEligible'], 'properties': {'tag': {'type': 'string', 'description': 'Column K group (client/project/trip).'}, 'date': {'type': 'string'}, 'amount': {'type': 'number', 'description': 'Functional/home-currency amount.'}, 'dateIso': {'type': 'string', 'description': 'Canonical YYYY-MM-DD when available.'}, 'category': {'type': 'string'}, 'currency': {'type': 'string', 'description': 'Home currency code when available.'}, 'location': {'type': 'string'}, 'merchant': {'type': 'string'}, 'expenseId': {'type': 'string', 'description': 'Durable Receipt ID (Column Q). The only identity accepted by update_expense.'}, 'matchReason': {'type': 'string'}, 'matchedFields': {'type': 'array', 'items': {'type': 'string'}}, 'originalAmount': {'type': 'number'}, 'updateEligible': {'type': 'boolean'}, 'originalCurrency': {'type': 'string'}}, 'additionalProperties': True}, 'description': 'Matching expense rows, newest first, paginated.'}, 'pageInfo': {'type': 'object', 'additionalProperties': True}, 'nextCursor': {'type': ['string', 'null'], 'description': 'Opaque signed continuation; reuse with identical filters.'}, 'queryApplied': {'type': 'string'}, 'totalMatched': {'type': 'integer', 'description': 'Present for free-text searches.'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'default': 5, 'maximum': 10, 'minimum': 1, 'description': 'Number of ranked matching articles to return (1-10).'}, 'query': {'type': 'string', 'description': 'Search terms'}, 'fullAnswer': {'type': 'boolean', 'default': False, 'description': 'Set true on the first call for complete, detailed, or step-by-step instructions. Leave false for discovery or quick-answer excerpts.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'results'], 'properties': {'results': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'question', 'answer'], 'properties': {'id': {'type': 'string'}, 'type': {'type': 'string'}, 'answer': {'type': 'string'}, 'question': {'type': 'string'}, 'relevance': {'type': 'number'}, 'truncated': {'type': 'boolean'}}, 'additionalProperties': True}}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['provider'], 'properties': {'mode': {'enum': ['auto', 'expense', 'bill'], 'type': 'string', 'description': 'Step 1 only (Zoho Books): automatic document treatment, paid expenses, or bills.'}, 'confirm': {'type': 'boolean', 'description': 'Step 2 only: true posts the exact staged proposal. No other options may change.'}, 'provider': {'enum': ['zoho_books'], 'type': 'string', 'description': 'Accounting destination provider. Agent-driven posting is currently available only for Zoho Books.'}, 'reportId': {'type': 'string', 'description': 'Step 1 only: ExpenseBot report ID owned by the signed-in account.'}, 'proposalId': {'type': 'string', 'description': 'Step 2 only: proposalId returned by the read-only preview.'}, 'forceRepush': {'type': 'boolean', 'description': 'Step 1 only: explicitly include disclosed uncertain prior outcomes in the frozen proposal.'}, 'taxMappings': {'type': 'object', 'description': 'Step 1 only: observed tax-rate string to live destination tax ID overrides.', 'additionalProperties': {'type': 'string'}}, 'accountMappings': {'type': 'object', 'description': 'Step 1 only: ExpenseBot category to live destination account ID overrides.', 'additionalProperties': {'type': 'string'}}, 'reportingTagMappings': {'type': 'object', 'description': 'Step 1 only: ExpenseBot tag to live destination reporting-tag option.', 'additionalProperties': {'type': 'object', 'required': ['tagId', 'optionId'], 'properties': {'tagId': {'type': 'string', 'description': 'Live accounting-provider reporting-tag ID returned in the step-1 proposal.'}, 'optionId': {'type': 'string', 'description': 'Live option ID belonging to tagId, returned in the step-1 proposal.'}}}}}}
Schéma de sortie
{'type': 'object', 'allOf': [{'if': {'required': ['phase'], 'properties': {'phase': {'const': 'preview'}}}, 'then': {'required': ['expiresAt', 'confirmationRequired', 'confirmationQuestion', 'confirmationContract']}}, {'if': {'required': ['phase'], 'properties': {'phase': {'const': 'completed'}}}, 'then': {'required': ['reportId', 'finalAnswer', 'responseGuidance']}}], 'required': ['success', 'phase', 'provider', 'proposalId'], 'properties': {'phase': {'enum': ['preview', 'completed'], 'type': 'string'}, 'units': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'counts': {'type': 'object', 'additionalProperties': True}, 'created': {'type': 'integer', 'minimum': 0}, 'success': {'type': 'boolean'}, 'provider': {'type': 'string'}, 'reportId': {'type': 'string'}, 'expiresAt': {'type': 'string', 'format': 'date-time'}, 'proposalId': {'type': 'string'}, 'finalAnswer': {'type': 'string'}, 'organization': {'type': 'object', 'additionalProperties': True}, 'matchedExisting': {'type': 'integer', 'minimum': 0}, 'omittedExpenses': {'type': 'integer', 'minimum': 0}, 'idempotentReplay': {'type': 'boolean'}, 'responseGuidance': {'type': 'string'}, 'confirmationContract': {'type': 'string'}, 'confirmationQuestion': {'type': 'string'}, 'confirmationRequired': {'type': 'boolean'}, 'skippedAlreadyPushed': {'type': 'integer', 'minimum': 0}, 'reconciliationRequired': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['reportId', 'recipients'], 'properties': {'reportId': {'type': 'string'}, 'recipients': {'type': 'array', 'items': {'type': 'string', 'format': 'email'}}, 'recipientRole': {'enum': ['reviewer', 'accountant'], 'type': 'string', 'default': 'reviewer', 'description': 'Use reviewer for report-only approval. Use accountant only for explicit ongoing accountant access.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'message', 'sharedWith', 'recipientRole'], 'properties': {'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'sharedWith': {'type': 'array', 'items': {'type': 'string', 'format': 'email'}}, 'finalAnswer': {'type': 'string'}, 'recipientRole': {'type': 'string'}, 'responseGuidance': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': [], 'properties': {'tag': {'type': 'string', 'description': 'Batch-level project or client tag applied to every expense row. Individual files may override it. Stored in the Tag column (K) through the same path as the web receipt uploader.'}, 'note': {'type': 'string', 'description': 'Batch-level context note applied to every file in the upload. Individual files may override this with their own note. Stored through the existing receipt-note pipeline in the Notes column (L).'}, 'photo': {'type': 'object', 'required': ['download_url', 'file_id'], 'properties': {'file_id': {'type': 'string', 'description': 'Attachment identifier supplied by ChatGPT.'}, 'file_name': {'type': 'string', 'description': 'Original attachment filename supplied by ChatGPT.'}, 'mime_type': {'type': 'string', 'description': 'Attachment MIME type supplied by ChatGPT.'}, 'download_url': {'type': 'string', 'format': 'uri', 'description': 'Temporary HTTPS URL supplied by ChatGPT for downloading the attachment.'}}, 'description': 'Single attached receipt image or PDF supplied by ChatGPT. For multiple files or large files, use filesToUpload and uploadRefs instead.'}, 'filename': {'type': 'string', 'description': "Optional filename (e.g., 'lunch_receipt.jpg')"}, 'mimeType': {'enum': ['image/jpeg', 'image/png', 'image/heic', 'image/webp', 'application/pdf'], 'type': 'string', 'description': 'MIME type of the file (default: image/jpeg)'}, 'uploadRef': {'type': 'string', 'description': 'Single-file shorthand for uploadRefs. Use uploadRefs when there is more than one file.'}, 'uploadRefs': {'type': 'array', 'items': {'type': 'object', 'required': ['uploadRef'], 'properties': {'id': {'type': 'string', 'description': 'The id you supplied in filesToUpload.'}, 'tag': {'type': 'string', 'description': 'Project or client tag for this specific file. Overrides the batch-level tag and is stored in the Tag column (K).'}, 'note': {'type': 'string', 'description': 'Context note for this specific file. Overrides the batch-level note if both are provided. Uses the existing receipt-note pipeline and is stored in the Notes column (L).'}, 'uploadRef': {'type': 'string', 'description': 'uploadRef returned for that file.'}}}, 'description': 'Submit previously uploaded files as ONE batch. Include every uploadRef from the filesToUpload step. If any file fails validation the whole batch is rejected and nothing is processed.'}, 'photoBase64': {'type': 'string', 'description': 'Legacy fallback for MCP clients that send one small image as complete base64 data. ChatGPT should use photo or uploadRefs instead.'}, 'filesToUpload': {'type': 'array', 'items': {'type': 'object', 'required': ['filename'], 'properties': {'id': {'type': 'string', 'description': "Your own identifier for this file, echoed back so you can match URLs to files. E.g. '1', '2'."}, 'filename': {'type': 'string', 'description': "Original filename, e.g. 'lunch.jpg' or 'invoice.pdf'."}, 'mimeType': {'enum': ['image/jpeg', 'image/png', 'image/heic', 'image/heif', 'image/webp', 'application/pdf'], 'type': 'string', 'description': "MIME type. Must match the Content-Type header used in the PUT exactly. The real format is re-detected from the file's contents on submit, so a close guess still works."}}}, 'description': 'Request upload URLs for one or more files. Include EVERY file the user provided in a single call. Returns one signedUrl + uploadRef per file; upload each, then call this tool again with uploadRefs.'}}}
Schéma de sortie
{'type': 'object', 'allOf': [{'if': {'required': ['status'], 'properties': {'status': {'const': 'upload_required'}}}, 'then': {'required': ['data']}}], 'required': ['success'], 'properties': {'data': {'type': 'object', 'properties': {'files': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'filename': {'type': 'string'}, 'mimeType': {'type': 'string'}, 'signedUrl': {'type': 'string'}, 'uploadRef': {'type': 'string'}, 'requiredHeaders': {'type': 'object', 'additionalProperties': {'type': 'string'}}}, 'additionalProperties': True}}, 'signedUrl': {'type': 'string'}, 'uploadRef': {'type': 'string'}, 'submissionId': {'type': 'string'}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'requiredHeaders': {'type': 'object', 'additionalProperties': {'type': 'string'}}, 'expiresInSeconds': {'type': 'integer', 'minimum': 1}, 'reviewExpensesUrl': {'type': 'string'}}, 'additionalProperties': True}, 'files': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'status': {'type': 'string'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'fileCount': {'type': 'integer', 'minimum': 0}, 'statusCode': {'type': 'integer'}, 'submissionId': {'type': 'string'}, 'spreadsheetUrl': {'type': ['string', 'null']}, 'reviewExpensesUrl': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {'days': {'type': 'integer', 'default': 30, 'maximum': 180, 'minimum': 1, 'description': 'How many days back to search.'}, 'limit': {'type': 'integer', 'default': 80, 'maximum': 250, 'minimum': 1, 'description': 'Maximum lineage events to return.'}, 'query': {'type': 'string', 'description': "Merchant, sender, subject, invoice number, or phrase to search for, e.g. 'Blue Rocket', 'Driversnote', 'Uber receipt'."}, 'outcome': {'enum': ['all', 'created', 'skipped', 'suggested', 'income_routed', 'deduped', 'removed_as_duplicate'], 'type': 'string', 'default': 'all', 'description': 'Optional processing outcome filter.'}, 'threadId': {'type': 'string', 'description': 'Gmail thread ID if known.'}, 'messageId': {'type': 'string', 'description': 'Gmail message ID if known.'}, 'receiptId': {'type': 'string', 'description': 'ExpenseBot receipt/invoice ID if known, e.g. IR-123, RO-abc, RR-456.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'type', 'message', 'data'], 'properties': {'data': {'type': 'object', 'properties': {'events': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'filters': {'type': 'object', 'additionalProperties': True}, 'summary': {'type': 'object', 'additionalProperties': True}, 'searchLabel': {'type': 'string'}}, 'additionalProperties': True}, 'type': {'type': 'string', 'const': 'lineage_trace'}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['expenseId', 'fields'], 'properties': {'fields': {'type': 'object', 'properties': {'tag': {'type': 'string'}, 'category': {'type': 'string'}, 'merchant': {'type': 'string'}, 'businessPurpose': {'type': 'string'}}, 'description': 'Partial update object. Include one or more of these optional keys; omit every field that should remain unchanged.', 'maxProperties': 4, 'minProperties': 1, 'additionalProperties': False}, 'confirm': {'type': 'boolean', 'description': 'Omit or false = preview only (no write). Must be exactly true to apply the change.'}, 'expenseId': {'type': 'string', 'description': 'Exact full Receipt ID from Column Q, returned as expenseId by search_expenses.'}}}
Schéma de sortie
{'type': 'object', 'required': ['success', 'message', 'data'], 'properties': {'data': {'type': 'object', 'required': ['applied', 'expenseId', 'diff', 'unmapped'], 'properties': {'diff': {'type': 'array', 'items': {'type': 'object', 'required': ['field', 'from', 'to'], 'properties': {'to': {}, 'from': {}, 'field': {'type': 'string'}, 'column': {'type': 'string'}, 'columnLetter': {'type': 'string'}}, 'additionalProperties': True}}, 'dryRun': {'type': 'boolean'}, 'applied': {'type': 'boolean'}, 'preview': {'type': 'boolean'}, 'unmapped': {'type': 'array', 'items': {'type': 'string'}}, 'expenseId': {'type': 'string'}, 'reviewExpenseUrl': {'type': 'string'}}, 'additionalProperties': True}, 'message': {'type': 'string'}, 'success': {'type': 'boolean'}, 'finalAnswer': {'type': 'string'}, 'responseGuidance': {'type': 'string'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['deltaMonthly'], 'properties': {'deltaMonthly': {'type': 'number', 'minimum': 0, 'description': "The new recurring monthly cost being considered, in the user's home currency"}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'description': 'The full what-if scenario: assumptions, evidence, and computed outcome.', 'additionalProperties': True}, 'message': {'type': 'string', 'description': 'Scenario narrative; may be absent if the scenario carried no template or evidence.'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'required': ['clientName', 'mode'], 'properties': {'mode': {'enum': ['late30', 'gone'], 'type': 'string', 'description': "'late30' = shift open invoices 30 days late; 'gone' = client stops paying entirely"}, 'clientName': {'type': 'string', 'description': "The client's name as it appears on invoices or income rows"}}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'description': 'The full what-if scenario: assumptions, evidence, and computed outcome.', 'additionalProperties': True}, 'message': {'type': 'string', 'description': 'Scenario narrative; may be absent if the scenario carried no template or evidence.'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Schéma d’entrée
{'type': 'object', 'properties': {}}
Schéma de sortie
{'type': 'object', 'required': ['success'], 'properties': {'data': {'type': 'object', 'description': 'The full what-if scenario: assumptions, evidence, and computed outcome.', 'additionalProperties': True}, 'message': {'type': 'string', 'description': 'Scenario narrative; may be absent if the scenario carried no template or evidence.'}, 'success': {'type': 'boolean'}}, 'additionalProperties': True}
Modifications récentes des outils
Serveurs MCP similaires
Lovie Company Formation
Supports company formation and business administration with bank accounts, cards, invoicing, bookkeeping, accounting periods, and…
Stratalize Finance
Provides financial, macroeconomic, banking, credit, commodities, M&A, ESG, labor, and regulatory benchmarks for analysis and plan…
Red by Big Red Cloud
Connects to Big Red Cloud accounting for customers, suppliers, products, invoices, purchases, payments, receipts, journals, quote…
GestãoClick
Connects to the GestãoClick ERP to manage customers, suppliers, products, sales, service orders, budgets, and financial records.
Superlógica Condomínios
Connects to a condominium ERP for billing, collections, agreements, expenses, bank movements, statements, files, communications, …
FalaZuki Finance BR
Provides Brazil-focused financial calculations and rules for investments, credit, taxes, payroll, labor costs, debt, budgeting, a…
XBOSS
Accesses Korean tax, social insurance, payroll, cash receipt, e-tax invoice, and certificate filing services.
Sirenic
Provides European company registry, financial, procurement, sanctions, regulatory, insolvency, ownership, and ongoing due-diligen…