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.

At its smallest size the card draws the figure alone. It carries the figure, the window it averages and the trend chip. At its wider sizes it draws a donut of by_context when you send it, and the donut labels each slice from its key. The recurring contexts reach the card only through that split; they are not drawn as a list. Everything else you state below is REQUIRED and is not drawn. 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.

OPTIONAL, and sent whenever you can state it:

  • by_context — the same average split by billing context: one entry per key in recurring_contexts, each { key, amount }, where amount is that context's own monthly average over the same window, the same divisor and the same conversion as amount. Send EVERY recurring context, the largest first, and do not group any of them yourself: the server keeps the 4 largest by name and folds the rest, and every slice under 1.5% of the total, into one "Other" slice. Send no label and no share. The server names each context from its key and derives each share from the amounts, and returns both. When a context nets negative over the window, send no by_context at all: a split cannot draw a negative slice, and the figure still renders alone.

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. The card names a few of them at most, and none at its smallest size, 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

  • a by_context whose keys are not exactly recurring_contexts (a key the list does not hold, a key sent twice, or a recurring context left out), whose amounts are negative, whose amounts do not add up to amount (a cent of slack per entry), or whose entries are not sorted by amount, largest first

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 workspace 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.
by_contextNoThe average split by billing context: every recurring context once, largest first, no label and no share. The server names each context and derives each share.
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.
workspace_scopeNoRestrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.
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
by_contextNo
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.
newly_connectedNoTools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.
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. Changed1 schema field changed
    • changedOutput schema / properties / newly_connected / description
      Previous value: -"Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. Start the reply with one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later."New value: +"Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later."
  2. Changed1 schema field changed
    • addedInput schema / properties / workspace_scope
      Added value: +{
      +  "description": "Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.",
      +  "enum": [
      +    "family"
      +  ],
      +  "type": "string"
      +}
  3. Changed1 schema field changed
    • addedOutput schema / properties / newly_connected
      Added value: +{
      +  "description": "Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. Start the reply with one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "name": {
      +        "type": "string"
      +      },
      +      "service_id": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "service_id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  4. Changed2 schema fields changed
    • addedInput schema / properties / by_context
      Added value: +{
      +  "description": "The average split by billing context: every recurring context once, largest first, no label and no share. The server names each context and derives each share.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "amount": {
      +        "description": "This context's own monthly average, in `currency`, over the same window and divisor.",
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "key": {
      +        "description": "One key of `recurring_contexts`, exactly as sent there.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "key",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 100,
      +  "type": "array"
      +}
    • addedOutput schema / properties / by_context
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "amount": {
      +        "type": "number"
      +      },
      +      "is_other": {
      +        "const": true,
      +        "type": "boolean"
      +      },
      +      "key": {
      +        "type": "string"
      +      },
      +      "label": {
      +        "type": "string"
      +      },
      +      "pct": {
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "key",
      +      "label",
      +      "amount",
      +      "pct"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  5. 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"
      +}
  6. Added

TDQS

Score is being calculated.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources