Skip to main content
Glama

List the billing contexts a reader can count as recurring

well_list_recurring_contexts
Read-only

List the billing contexts a reader can count as recurring revenue over one window, each with what counting it would add. This is what the recurring-contexts card offers; it measures nothing well_sum_invoices did not already measure.

Each entry in groups is one billing context's revenue in the window: context_key (the id a selection is matched on), label (the context as the product writes it), amounts (one entry per currency, each already net of credit notes and never converted) and count (the invoices behind it). The named contexts are sorted biggest first in the currency that carries the most invoices, so the biggest decision reads first. A context whose window nets to nothing in every currency is NOT listed — counting it would add nothing, so it is not a choice. A context that nets NEGATIVE stays on the list: its credit notes outweighed its invoices, which is a real state, and hiding it would move the figure by an amount nobody saw.

The last entry may be context_key: "unclassified", labelled "No billing context". It is the invoices whose billing_context is null: extraction fills the field rather than a billing system, so on most workspaces it holds most of the revenue. It is a choice like the others. A business that bills only subscriptions can count it as recurring; a business with one-off work usually cannot. When the reader counts it, apply it to the well_sum_invoices rows whose billing_context is null — no row carries the key itself. State its amount whenever it is listed, counted or not, because it is the part of the figure extraction could not describe.

totals is the sum of the groups' amounts per currency: the window's whole readable issued revenue. This read converts nothing and never adds one currency to another. The reader decides per context, so the choice needs no single total; convert once, in the arithmetic, at a rate you state.

This read takes no view on which contexts ARE recurring, and offers no default, the "No billing context" entry included. What counts as recurring revenue is a fact about the reader's business, not about the vocabulary: a retainer is recurring for one company and a one-off engagement for another.

Take the reader's answer from the card: its Continue records it with well_switch_workspace as recurring_contexts, and you read it back with well_wait_for_selection (kind "recurring_contexts"). Keep only the well_sum_invoices rows whose billing_context is in that answer, reading unclassified as the rows whose billing_context is null, and pass the same keys to well_render_mrr as recurring_contexts so the figure names what it counted.

The window is whole months: from and to are both the first day of a month, YYYY-MM-01, from inclusive and to EXCLUSIVE. window echoes both back exactly as you sent them. When a comparison will be measured, read the list over BOTH windows, from the start of the earlier one to the end of this one, so a context that stopped billing between them is still offered.

partial: true means the aggregate was cut short: every amount here is a FLOOR, a context's real share can only be larger, and a choice made because a share looked small may not survive the full read. Say so before presenting the list as a basis for the decision. unreadable_rows counts invoices whose net amount or currency could not be read at all; they are in no figure here. It is null when that count could not be read, which is not zero: say it is unmeasured.

Read success before groups: a failed read returns no contexts, which looks exactly like a window with nothing to choose.

When the token authorizes one workspace, call this directly — no other tool call is needed first. When it authorizes several, this read will not guess which one you mean: pass workspace_id on the call.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toYesEXCLUSIVE end of the window: the first day of the month after the last one you want, YYYY-MM-01.
fromYesInclusive start of the window: the first day of a month, YYYY-MM-01.
workspace_idNoTarget workspace. Omit when the token authorizes one workspace. Required when it authorizes several: this read reports one workspace's own figures and will not choose which.
conversation_idNoThe conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNo
groupsYes
totalsYes
windowYes
partialYesTrue when the aggregate behind these figures was cut short. Every amount is then a FLOOR rather than a measurement.
successYes
next_stepNoWhat to do with the card this result renders. Added by the dispatcher when the card asks for a click.
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
unreadable_rowsYesInvoices in the window whose net amount or currency could not be read. They are in no figure here, including the no-billing-context one. Null when the count could not be read.
resolved_workspaceNoThe workspace that answered, when the caller named none and the token authorizes several.
conversation_id_noteNoPresent only when the server opened a fresh lane, stating that no choice recorded earlier was read.
conversation_id_sourceNoWhere the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_note
      Added value: +{
      +  "description": "Present only when the server opened a fresh lane, stating that no choice recorded earlier was read.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_source
      Added value: +{
      +  "description": "Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.",
      +  "enum": [
      +    "host_meta",
      +    "argument",
      +    "minted"
      +  ],
      +  "type": "string"
      +}
  2. Added

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already mark this as read-only and non-destructive, so the description's job is to add behavioral context. It adds a great deal: no currency conversion, no built-in default for what counts as recurring, negative contexts stay listed, zero contexts are omitted, `partial: true` means amounts are floors, `unreadable_rows` can be null-but-not-zero, and `success` must be read before `groups`. None of this is in the 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 the tool has nuanced output semantics and decision-support caveats that justify the length. It is front-loaded with purpose, uses bolded key concepts, and organizes content into coherent blocks: entries, totals, no-default stance, workflow, window rules, and failure semantics. A few sentences are somewhat expansive, but most earn their place.

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?

Despite having an output schema, the description explains the full shape of `groups`, `totals`, `unclassified`, sorting, partial reads, unreadable rows, and failure behavior. It also covers multi-workspace authentication and the exact follow-up workflow with sibling tools. Nothing an agent needs to call and interpret this tool correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description reinforces `from` inclusive / `to` exclusive and workspace-auth behavior, but those are already fully described in the schema. It adds a little output-behavior context (`window` echoes back, `partial` floors amounts), but not enough new parameter-level meaning to push above the baseline.

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 opens with a specific verb+resource: 'List the billing contexts a reader can count as recurring revenue over one window, each with what counting it would add.' It also distinguishes itself from a sibling by noting it 'measures nothing `well_sum_invoices` did not already measure,' so an agent can tell this is the choice-presentation read rather than the revenue-summing read.

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 explicit when-to-call guidance: 'When the token authorizes one workspace, call this directly' and 'When it authorizes several... pass workspace_id on the call.' It also explains when to read over both windows for comparisons, and describes how the result feeds into `well_switch_workspace`, `well_wait_for_selection`, and `well_render_mrr`. This is far beyond implied usage.

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.

Resources