Skip to main content
Glama

Render a caller-computed recurring revenue figure

well_render_mrr
Read-only

Put an MRR figure YOU computed onto the MRR card.

This tool measures nothing. It takes the figure and its method as input and returns them for rendering. Call it only after you have computed the recurring revenue yourself and can state every field below from your own work — never to "get" an MRR.

The server derives no MRR of its own. The figure on the card is the one you state here, which is why every field below is required: the policy behind a number is the only thing that makes it checkable.

Under the number the card draws nothing. It carries the figure, the window it averages and the trend chip; everything else you state below is REQUIRED and reaches no pixel. All of it comes back in this tool's text result, which is what you write the prose from. The card is the measure; the explanation is yours.

REQUIRED, because a figure whose method is not stated cannot be checked:

  • amount — the recurring revenue per month in currency, net of tax and of credit notes, as the sum returned it

  • window — the months the average divides by, not the months that carried revenue

  • months_in_window and months_with_revenue — a window with dark months reports LOWER than its typical month. When the two differ you MUST say so in prose: how many months recorded recurring revenue, and that the average still divides by the whole window

  • recurring_contexts — the billing contexts the reader confirmed as recurring, as the keys the card recorded. "unclassified" among them means the reader counted the invoices with no billing context (the sum rows whose billing_context is null) as recurring. This is the reader's half of the policy and the card cannot show it, so an answer that does not name them leaves the figure unchecked

  • invoice_count, unattributed_count and unclassified_count — how much of the window the figure could reach at all. invoice_count is the issued invoices; unattributed_count is the SEPARATE set Well could place on neither side, reported beside it rather than inside it, and it may be larger. An unattributed invoice may still be recurring revenue. An unclassified one carries no billing context: it is in the figure only when recurring_contexts holds "unclassified", and when it is, say in prose that the reader chose to count it. Send null for a count the sum returned as null: it is unmeasured, not zero

  • excluded — what fell out, as three invoice COUNTS kept apart: one_off (issued invoices under a context the reader did not count), credit_notes (the credit_note_count netted into the figure) and unreadable_rows (the sum's excluded_malformed, null when unmeasured)

REFUSED rather than rendered, each because your own figures disagree with each other:

  • a negative amount — the credit notes outweighed the recurring invoices, so net recurring revenue fell below zero. That is a finding to report in prose, not a figure to put on a card, and never one to flip to its magnitude

  • an empty recurring_contexts — an MRR with nothing counted as recurring is not an MRR of zero, it is a policy nobody stated. Say the figure has nothing to measure instead

  • months_with_revenue above months_in_window, or unclassified_count above invoice_count

  • a months_in_window that disagrees with the months window spans — the two state one fact

  • a window whose bounds are not month starts — a month-average divides by whole months

  • change with no baseline, a baseline.value of zero, a baseline that does not start before the window or spans a different number of months, or a change whose magnitude or sign its own two figures contradict

  • a per_month series that does not name each month of the window once in order, does not average to amount, or disagrees with months_with_revenue

Send baseline and change as a pair or send neither. Do not send a direction: the card's colour is decided server-side from the figures. Revenue is higher-is-better, which is the opposite of the burn card and exactly why a caller does not get to state it.

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
amountYesRecurring revenue per month, net of tax and credit notes. A negative net is refused, never flipped.
changeNoSigned percentage against `baseline.value`, drawn as the card's trend chip. Send it only alongside `baseline`.
windowYesInclusive start and EXCLUSIVE end of the averaged window, YYYY-MM-DD.
baselineNoThe earlier window this figure is compared against. Required for `change` to render, and never rendered itself: name it in prose.
currencyYesISO-4217 code the amount is denominated in.
excludedYesThe three exclusion groups kept apart: the reader's choice, the structural netting, and the defective rows.
per_monthNoThe series behind the average. A month with no recurring revenue belongs in it as a zero.
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.
invoice_countYesIssued invoices in the window.
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.
months_in_windowYesThe divisor — every month in the window.
recurring_contextsYesThe billing contexts the reader confirmed as recurring, as recorded keys; "unclassified" stands for the invoices with no billing context. At least one: an MRR counting nothing as recurring is a policy nobody stated, not a zero.
unattributed_countYesInvoices Well could place on neither side: a set separate from `invoice_count`, which may be larger. Null when unmeasured.
unclassified_countYesInvoices carrying no billing context. In the figure only when `recurring_contexts` holds "unclassified".
months_with_revenueYesHow many of those months carried any recurring revenue.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
trendNo
amountYes
changeNo
windowYes
successYes
baselineNo
currencyYes
excludedYes
per_monthNo
computed_byYes
invoice_countYes
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
months_in_windowYes
recurring_contextsYes
resolved_workspaceNoThe workspace that answered, when the caller named none and the token authorizes several.
unattributed_countYes
unclassified_countYes
months_with_revenueYes
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.9/5.0
Behavior5/5

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

Annotations declare readOnlyHint=true and destructiveHint=false, and the description adds substantial behavioral detail: it does not compute MRR, it returns the figure and method for rendering, refusal conditions (negative amount, empty recurring_contexts, etc.), and the fact that only certain fields reach the card while others are only in the text result. No contradiction with 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 well-structured with clear sections (REQUIRED, REFUSED, usage notes). It is front-loaded with the key message, and every sentence adds necessary detail for a 15-parameter tool. Some redundancy with schema descriptions exists, but the overall organization earns a high score, just not a perfect one.

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 high complexity (15 params, 10 required, nested objects, output schema), the description covers every operational aspect: what to compute, what to send, refusal conditions, workspace handling, and the output text result. Nothing an agent needed to call correctly is missing.

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

Parameters5/5

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

Schema coverage is 100% with rich descriptions, and the tool description goes further: it explains the meaning of window vs months_with_revenue, the significance of unclassified contexts, the role of unattributed_count as a separate set, and refusal logic. This adds substantial semantic context beyond the schema, making parameter usage checks explicit.

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 precise verb and resource: 'Put an MRR figure YOU computed onto the MRR card.' It explicitly distinguishes itself from calculation tools ('This tool measures nothing') and from the burn card (revenue is higher-is-better, opposite of the burn card). This makes its role unambiguous relative to siblings.

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?

It clearly says when to call ('only after you have computed the recurring revenue yourself — never to get an MRR') and provides workspace guidance (call directly for single workspace; pass workspace_id for multiple). It also states when to send baseline/change as a pair, and contrasts with the burn card to help select between tools.

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