Skip to main content
Glama

group_expenses

Destructive

Group an exact set of recorded expenses for a client, project, trip, job, or other user-named purpose. Examples: 'group my Mexico meals for client Rob', 'put these Vegas expenses under the Vegas project', or 'group these for client Rob and create a report'. The user does not need to know about tags: ExpenseBot resolves the requested name against existing groups and proposes creating one only when needed. Use exact expenseId values returned by search_expenses. A grounded preview is automatic for every bulk request; the user does not need to ask for one. First call with confirm omitted/false, show the returned exact rows, count, totals, proposed group, exclusions, and conflicts, then ask for approval. Only after explicit user approval, repeat the same operationId and selection with confirm:true. A premature confirm:true is converted to preview. When the request includes a report, set createReport:true on that confirmed group_expenses call and use its report result; do not run a separate broader create_report query. For 'without personal expenses', set excludePersonal:true; ExpenseBot removes Personal-tagged and Personal-category rows before preview so their Personal marker is never overwritten. The confirmed operation returns exact report and Bill Client links. Expenses already assigned to another ordinary report are excluded; if none remain, no duplicate report is created and the result links to Reports instead. Keep the user-facing response concise and do not add unsolicited tax or substantiation advice. Do not call check_compliance, get_report_details, or tax/deductibility tools before or after this workflow unless the user explicitly asks for that separate analysis. In user-facing prose call the destination a group, not a tag. Treat preview totals as provisional; after confirmation use only the terminal result's exact count, total, and currency without reconciling it against the preview. A returned Bill Client URL opens the reviewed billing handoff and does not mean an invoice was created, sent, or confirmed. Sharing remains a separate share_report action with recipient confirmation.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
undoNoUndo a completed grouping within its undo window.
groupNoThe user-named destination group to apply to every eligible selected expense.
statusNoRead operation status using operationId.
confirmNoOmit/false for preview; true only after explicit approval.
selectionNoExact expenses returned by search_expenses and approved for this bounded operation.
operationIdYesStable idempotency key generated once for the preview and reused unchanged.
reportTitleNoOptional title when createReport is true; otherwise ExpenseBot derives one from the group.
createReportNoCreate a report from the exact eligible grouped expenses.
excludedTagsNoExisting groups to exclude before preview and grouping.
approveNewGroupNoTrue only when the preview says a new group is required.
excludePersonalNoExclude Personal-tagged and Personal-category expenses from both grouping and the exact report.
excludedCategoriesNoExpense categories to exclude before preview and grouping.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -{
      -  "additionalProperties": true,
      -  "description": "Standard ExpenseBot tool result envelope. `message` is the human-readable summary the AI cites; `data` is the structured payload (totals, breakdowns, ids, etc.). On failure, `success` is false and `error` carries a code/message/hint triple.",
      -  "properties": {
      -    "data": {
      -      "additionalProperties": true,
      -      "description": "Structured payload. Shape varies per tool — common keys: total, breakdown, comparison, sampleMeta, ids, expenseId, reportId, signupUrl, results.",
      -      "type": "object"
      -    },
      -    "error": {
      -      "additionalProperties": true,
      -      "description": "Present only when success === false.",
      -      "properties": {
      -        "code": {
      -          "type": "string"
      -        },
      -        "hint": {
      -          "type": "string"
      -        },
      -        "message": {
      -          "type": "string"
      -        }
      -      },
      -      "type": "object"
      -    },
      -    "message": {
      -      "description": "Human-readable result text. Always present on success; prefer rendering this verbatim before any further reasoning.",
      -      "type": "string"
      -    },
      -    "sampleMeta": {
      -      "additionalProperties": true,
      -      "description": "Set when the underlying dataset was truncated. isTruncated=true means the agent saw a sample of `sampleCount` of `totalCount` rows; aggregate totals are still accurate.",
      -      "properties": {
      -        "isTruncated": {
      -          "type": "boolean"
      -        },
      -        "sampleCount": {
      -          "type": "integer"
      -        },
      -        "totalCount": {
      -          "type": "integer"
      -        }
      -      },
      -      "type": "object"
      -    },
      -    "success": {
      -      "description": "False on tool errors; check before reading `data`.",
      -      "type": "boolean"
      -    }
      -  },
      -  "type": "object"
      -}New value: +null
  2. Changed7 schema fields changed
    • addedInput schema / properties / group / description
      Added value: +"The user-named destination group to apply to every eligible selected expense."
    • addedInput schema / properties / group / properties / kind / description
      Added value: +"How to label the destination in user-facing confirmation text."
    • addedInput schema / properties / reportTitle / description
      Added value: +"Optional title when createReport is true; otherwise ExpenseBot derives one from the group."
    • addedInput schema / properties / selection / description
      Added value: +"Exact expenses returned by search_expenses and approved for this bounded operation."
    • addedInput schema / properties / selection / properties / items / description
      Added value: +"One exact receipt identity per selected expense; never broaden this list after preview."
    • addedInput schema / properties / selection / properties / items / items / properties / expected / description
      Added value: +"Optional current state copied from search results for conflict detection."
    • addedInput schema / properties / selection / properties / items / items / properties / expected / properties / tag / description
      Added value: +"Current group/tag value observed before preview; an empty string means ungrouped."
  3. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description explains crucial behaviors: a premature confirm:true becomes a preview, effective totals are provisional until the terminal result is used, the Bill Client URL is not an invoice, and Personal-tagged expenses are removed before preview. It also calls out destination naming semantics and duplicate report exclusions, giving the agent plenty of context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but earned and front-loaded with the central purpose and examples. Some sentences are dense or advisory, like directing the agent to keep a response concise, but the complexity of the operation and the many edge cases justify the length. No sentence seems wholly redundant with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description needed note the return content: preview shows exact rows, count, totals, proposed group, exclusions, and conflicts, while the confirmed call returns exact report and BillClient links. It also covers auto-preview, personal expense handling, report-linked exclusions, and user approval requirements, making the overall contract complete for this complex multi-phase tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already has descriptive parameter text with full coverage, so the baseline is 3. The description adds workflow-level meaning to key parameters such as confirm, operationId, selection, and excludePersonal, and clarifies conditional parameters like createReport and reportTitle. It does not further explain status or undo, but the schema already covers those sufficiently.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Group an exact set of recorded expenses' for a client, project, trip, job, or other user-named purpose, with multiple concrete examples. It also distinguishes this tool from siblings by explicitly disclaiming a separate create_report flow, so an agent can separate it from create_report, update_expense, and list_tags.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a precise workflow: call with confirm omitted/false for preview, show returned rows and totals, get explicit approval, then resend the same operationId and selection with confirm:true. It explicitly names alternatives and exclusions: use createReport on this call instead of running a separate create_report, do not call check_compliance or tax tools unless asked, and share_report remains separate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A3.6/5.0
Disambiguation3/5

Most tools are explicitly scoped, but several analytics/retrieval tools overlap in purpose, such as get_spending_summary vs get_deep_analytics vs get_monthly_books_review, and generic search vs search_expenses vs search_knowledge. The detailed descriptions help, but an agent still has to carefully choose between near-equivalent options like correct_expenses vs update_expense and the three add_income variants.

Naming Consistency5/5

Tool names consistently use lower_snake_case with a recognizable verb prefix: get_*, list_*, add_*, create_*, check_*, scan_*, search_*, and whatif_*. Minor exceptions like fetch and search are still terse retrieval verbs rather than a different naming style, so the overall pattern is predictable.

Tool Count1/5

With 59 tools, this exceeds the 50+ threshold for an extreme tool count and creates a heavy selection surface for an agent. Even though ExpenseBot covers many subdomains, many get_/list_/add_ variants could be consolidated into fewer parameterized tools. The count undermines the otherwise clear naming structure.

Completeness3/5

The surface is strong for creating, reading, and updating expenses, reports, invoices, and Gmail scans, but there are notable lifecycle gaps: no delete/void tools for expenses, income, reports, or invoices, and no update tool for income. Several descriptions explicitly redirect unsupported edits to the web app, confirming that the assistant cannot complete those workflows directly.