Skip to main content
Glama

List periods

well_list_periods
Read-only

List the recent accounting months of the workspace, with each month's close status, its invoice-retrieval state, and the counts that describe how much work it holds. Use this to ask the user WHICH month or months to work on before any close, review, or month-scoped read — do not guess a month, and do not derive one from today's date yourself.

Each entry carries:

  • calendar_year / calendar_month: the month itself.

  • fiscal_year / fiscal_period: the same month in the workspace's fiscal calendar — this is the pair every close endpoint and close tool takes.

  • label: the month written out, e.g. "March 2026".

  • is_complete: the calendar month has ended. A still-accruing month is never a valid close target.

  • selectable: the month can be CLOSED. False for a month that has not ended, one already closed, one with nothing to close, and a December whose year-end close is not supported yet. Read this one for a close pick.

  • analyzable: the month can be REPORTED ON. True once the month has ENDED and while it remains inside the window the canvas endpoints serve; false for the month in progress, for a future month, and for one too far back. It does NOT ask for a close verdict, because a report reads transactions and an unchecked month still has them. Read this one for an analysis pick.

  • inspectable: the month can be LOOKED INTO. A reader can open its transactions, its missing invoices and its days. True for EVERY month that has begun, the month in progress included. False only for a month that has not begun. It reads no close verdict and no activity count, so a closed month, an empty month and a workspace with no accounting connector at all still have readable months. An empty month answers with an empty list, which is an answer. Read this one for a retrieval or review pick; every selectable month is also inspectable.

  • close_status: "closeable" (ready), "not_ready" (work remains), "closed" (already locked), "nothing_to_close" (no activity), or null when the workspace has no verdict for that month.

  • close_reason: the blocking reason behind the status, or null.

  • invoice_state: "missing_invoices" (at least one counterparty still owes a supplier invoice), "has_invoices" (checked, and nothing is missing), or "none" (no state: no activity, the month has not begun, or the check could not run). Never read "none" as "nothing missing".

  • missing_invoice_count: how many counterparties owe an invoice for the month — the rows well_list_missing_invoices would return. 0 whenever invoice_state is "none", including when the check did not run.

  • transaction_count: how many transactions the month holds, dated on the basis this purpose measures on. analysis counts on executed_at, the same column well_sum_transactions ranges, so a month's count and a reporting figure cover the same WINDOW. It is not the same row set, and must never be quoted as the figure's row count: the sum can also drop internal transfers and exempt categories on request, and it widens to a parent's granted transactions where this count does not. Read it as a presence signal for the month. close and collect count on the books date, COALESCE(value_date, booking_date), which a transaction the bank has not booked does not carry — so a zero under those purposes means no BOOKED transaction, never an empty month.

  • bank_transaction_count: the subset of transaction_count delivered by a connector the workspace actually BANKS with, meaning a bank, a neobank, or a treasury or spend platform whose product is an account. An accounting platform and a payment processor deliver transactions too, so transaction_count is NOT a bank signal. Only this field answers "has a bank fed this month". A transaction counts as not-bank when its source connector is unknown, or when that connector has since been disconnected, so a zero here never licenses skipping a bank-connection step.

  • unposted_invoice_count: invoices the month HAS that have not posted to the ledger. This is a posting gap, not a missing invoice — do not present it as one.

  • uncategorized_transactions: transactions in the month not yet categorized — the "help categorize" errand behind a not-ready close. Dated on the books, so it is ABSENT under analysis rather than 0 — that purpose counts on execution and never measures this errand, and a 0 would read as "nothing left to categorize". It is also absent on a month the coverage read did not cover. Never read an absent count as "nothing left to categorize": say the month was not measured, or read it again.

  • categorized_unposted_transactions: categorized transactions not yet posted to the ledger — part of the "review and book" errand. Dated on the books, absent under analysis, and absent on an unmeasured month for the same reason.

  • invoice_state / missing_invoice_count: the month's invoice-retrieval verdict and the count behind it. Both are ABSENT on a month a analysis list skipped — that purpose bounds its invoice read by execution-dated activity while the errand is dated on the books, so the two disagree and a "none" there would be a claim nothing measured. Absent is not "owes nothing"; read it from a close or collect list.

  • days: the DAYS of the month that carry a retrieval state, ascending, each { day, state } over the same vocabulary as invoice_state. A day is "missing_invoices" when it holds settled expense spend still missing its supplier invoice, and "has_invoices" when it holds activity and no such gap. Days with neither are OMITTED, so an absent day means "none". days is empty for every month whose invoice_state is "none" — an unchecked month has no day the tool can call clean — and it is empty for EVERY month on a purpose: "analysis" call, whatever that month's invoice_state, because the reporting axis paints no day. On that purpose an empty days therefore says nothing about invoice coverage, and neither does an absent invoice_state. This is calendar detail for a picker to paint; quote the month's own counts, not a day list, when answering in prose.

  • analysis_days: present ONLY for a purpose: "analysis" call — the DAYS and whether a breakdown can name what each holds, ascending, each { day, state } over "categorized" / "uncategorized" / "neutral". An "uncategorized" day holds a transaction with no category. It still COUNTS toward a burn total, which filters on no category at all; a cost breakdown just reports it as uncategorised rather than under a named category. Never say a total is short because of it. Unlike the other two axes a quiet day IS listed, as "neutral". Calendar detail for the reporting picker.

  • close_days: present ONLY for a purpose: "close" call — the DAYS carrying a non-neutral close-readiness state, ascending, each { day, state } over "posted" / "progress". A day absent from it is "neutral" (nothing to close). Calendar detail for the close picker, like days is for retrieval.

default_period is the oldest month that is ready to close, falling back to the oldest still in progress. Offer it as the default choice. It reads selectable, so it is null whenever no month in the window can be CLOSED, and a null one does not mean the window is empty: an inspectable month can still be worked on for invoice retrieval. On a purpose: "analysis" call it is instead the NEWEST analyzable month, because a figure describes the latest ended period and a month outside the reporting window would be refused by the endpoints that serve it.

PURPOSE: pass purpose: "close" when the user is closing the books, so the picker paints close readiness and each month carries its close_days and the categorize / review counts. Pass purpose: "analysis" when a REPORTING SKILL is already running and is choosing the month its figure will cover, so the picker offers only analyzable months and paints the CATEGORIZATION day axis: neither invoice coverage nor close readiness is the decision being made, but an uncategorized day is one a breakdown cannot attribute. A user who merely mentions a report, a burn figure or a cost breakdown is NOT the trigger — naming one of those is phrasing, and phrasing never sets this field. Example: "What months do you have for me? I'm trying to work out my average burn." is a plain listing request that names a reason — it is NOT a reporting skill calling for its own period pick, so this call OMITS purpose. Only a caller that IS the reporting flow itself (an avg-burn/cost-structure/cash-flow-waterfall skill run, already past its own gates, now needing the month to compute against) passes "analysis" — never derive it from words in the user's own message, no matter how closely they match a report. Omit it (or purpose: "collect") for invoice retrieval, the default. This is the calling skill's intent — set it from the flow, never from the user's phrasing.

WINDOW: by default the months most recent calendar months, ending with the current one. Pass year instead to get ONE calendar year in full — all twelve of its months, December back to January — which is how you reach a year the recent window does not cover, backwards or forwards. navigable_years reports the range year is answered for.

A year ahead of today comes back in full and every month of it is selectable: false and inspectable: false with close_reason "period_not_ended": books close on a month that has ENDED, and a month that has not begun holds nothing to read. Show such months when the user asks to look ahead, and say why they cannot be picked. Never omit them.

COST: the invoice state is read per month from a separate endpoint, so a wide window costs one extra read for every month that holds activity, plus one day-coverage read per calendar year those months touch. A purpose: "analysis" call pays the same day-coverage read, dated on the execution basis, because it paints the categorization day axis. Ask for the months the user needs, not 24 by default. A wholly future or wholly empty year is cheap — no month in it can hold a settled gap, so none is read.

Call this directly — no other tool call is needed first (the workspace is resolved from the caller's authorized token, same as every other well_* tool).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
yearNoOne calendar year to return in full — all twelve of its months, December back to January, instead of the recent window. Use it to reach a year the recent window does not cover, in either direction; future months come back visible but never selectable. Accepted range: 2000-2100, also reported as `navigable_years`.
replyNoOne sentence, IN THE LANGUAGE THE USER IS WRITING IN, that the click sends into the conversation as their own message. Write what the PERSON would say about the months they pick, in their words, not an instruction to yourself. You write it BEFORE they click, so you cannot know what they will choose: put {picked} where the pick belongs and the card replaces it with the names they actually picked, one or several. In English it would read "Let's work on {picked}." Write the same shape in the user's language. {picked} is required: a sentence that names a pick itself names the one you guessed, so the card refuses it and sends its own English instead. At most 160 characters. Omitted sends an English sentence the card builds itself, which is wrong for any reader not writing in English.
titleNoHeading for the picker card shown to the user. At most 120 characters.
monthsNoHow many recent calendar months to return, ending with the current month. Each month holding activity costs one extra read for its invoice state. Ignored when `year` is given.
purposeNoWhy the months are being listed, set by the calling skill's own flow — never inferred from this message. "close" is book closure: the card paints close readiness, and each month carries its per-day `close_days` and the counts behind its "why not ready" errands. "analysis" is reporting: the card offers only the months a canvas can report on, paints the categorization day axis, counts on the execution date the canvas aggregates measure on, and therefore omits the books-dated errand counts entirely rather than reporting them as 0 — set it ONLY when a reporting skill is already running its own period-pick step, not just because this message names one (a burn figure, a cost breakdown, "my report"). Naming a report is phrasing; it never sets this field on its own. Omit or "collect" for invoice retrieval (the default, and the right choice for a plain "what months do you have" question, even one that mentions why) — this paints the retrieval axis and skips the close-readiness fields.
subtitleNoSupporting line under the picker card's heading. At most 240 characters.
workspace_idNoTarget workspace. This read reports one workspace's own data. Omit it and the token's primary workspace answers, which may not be the one you mean; the result names the workspace that did.
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
hintsNo
periodsYes
successYes
next_stepNoWhat to do with the card this result renders. Added by the dispatcher when the card asks for a click.
workspace_idYes
base_currencyYes
default_periodYes
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
navigable_yearsYesThe calendar years a `year` request is answered for. A picker's year steppers stop here.
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.
fiscal_year_start_monthYes

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. Changed2 schema fields changed
    • changedOutput schema / properties / periods / items / properties / categorized_unposted_transactions / description
      Previous value: -"Categorized transactions not yet posted to the ledger — part of the 'review and book' close errand. Dated on the books, and likewise ABSENT rather than 0 on a \"analysis\" call."New value: +"Categorized transactions not yet posted to the ledger — part of the 'review and book' close errand. Dated on the books, and likewise ABSENT rather than 0 on a \"analysis\" call and on a month the coverage read did not cover."
    • changedOutput schema / properties / periods / items / properties / uncategorized_transactions / description
      Previous value: -"Transactions in the month not yet categorized — the 'help categorize' close errand. Dated on the books, so it is ABSENT on a \"analysis\" call rather than 0: that purpose counts on execution and never measures this errand."New value: +"Transactions in the month not yet categorized — the 'help categorize' close errand. Dated on the books, so it is ABSENT on a \"analysis\" call rather than 0: that purpose counts on execution and never measures this errand. Absent too on a month the coverage read did not cover. An absent count is never \"nothing left to categorize\"."
  3. Changed1 schema field changed
    • addedInput schema / properties / reply
      Added value: +{
      +  "description": "One sentence, IN THE LANGUAGE THE USER IS WRITING IN, that the click sends into the conversation as their own message. Write what the PERSON would say about the months they pick, in their words, not an instruction to yourself. You write it BEFORE they click, so you cannot know what they will choose: put {picked} where the pick belongs and the card replaces it with the names they actually picked, one or several. In English it would read \"Let's work on {picked}.\" Write the same shape in the user's language. {picked} is required: a sentence that names a pick itself names the one you guessed, so the card refuses it and sends its own English instead. At most 160 characters. Omitted sends an English sentence the card builds itself, which is wrong for any reader not writing in English.",
      +  "maxLength": 160,
      +  "minLength": 1,
      +  "type": "string"
      +}
  4. Changed4 schema fields changed
    • changedInput schema / properties / purpose / description
      Previous value: -"Why the months are being listed, set by the calling skill's own flow — never inferred from this message. \"close\" is book closure: the card paints close readiness, and each month carries its per-day `close_days` and the counts behind its \"why not ready\" errands. \"analysis\" is reporting: the card offers only the months a canvas can report on, paints no day axis, counts on the execution date the canvas aggregates measure on, and therefore omits the books-dated errand counts entirely rather than reporting them as 0 — set it ONLY when a reporting skill is already running its own period-pick step, not just because this message names one (a burn figure, a cost breakdown, \"my report\"). Naming a report is phrasing; it never sets this field on its own. Omit or \"collect\" for invoice retrieval (the default, and the right choice for a plain \"what months do you have\" question, even one that mentions why) — this paints the retrieval axis and skips the close-readiness fields."New value: +"Why the months are being listed, set by the calling skill's own flow — never inferred from this message. \"close\" is book closure: the card paints close readiness, and each month carries its per-day `close_days` and the counts behind its \"why not ready\" errands. \"analysis\" is reporting: the card offers only the months a canvas can report on, paints the categorization day axis, counts on the execution date the canvas aggregates measure on, and therefore omits the books-dated errand counts entirely rather than reporting them as 0 — set it ONLY when a reporting skill is already running its own period-pick step, not just because this message names one (a burn figure, a cost breakdown, \"my report\"). Naming a report is phrasing; it never sets this field on its own. Omit or \"collect\" for invoice retrieval (the default, and the right choice for a plain \"what months do you have\" question, even one that mentions why) — this paints the retrieval axis and skips the close-readiness fields."
    • addedOutput schema / properties / next_step
      Added value: +{
      +  "description": "What to do with the card this result renders. Added by the dispatcher when the card asks for a click.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / periods / items / properties / analysis_days
      Added value: +{
      +  "description": "Days of the month and whether a breakdown can name what each one holds, ascending. Present ONLY for a \"analysis\" call. \"uncategorized\" means the day holds a transaction with no category — still counted in a burn total, but reported as uncategorised in a breakdown rather than under a named category; \"categorized\" means they all carry one; \"neutral\" means the day holds no transaction. Unlike the other two axes, a quiet day IS listed, as \"neutral\" — so a day absent from a non-empty list is one the read did not reach. An EMPTY list means the month was not measured at all, never that it holds nothing to categorize: check transaction_count, which is read separately, and treat a positive count beside an empty list as unmeasured. Calendar detail for the picker; quote the month's own counts in prose, not a day list.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "day": {
      +        "maximum": 31,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "state": {
      +        "enum": [
      +          "categorized",
      +          "uncategorized",
      +          "neutral"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "day",
      +      "state"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / periods / items / properties / days / description
      Previous value: -"Days of the month carrying a retrieval state, ascending. A day absent from this list is \"none\"; the list is empty whenever invoice_state is \"none\", and is ALWAYS empty on a \"analysis\" call, which paints no day axis — so an empty list there carries no invoice claim."New value: +"Days of the month carrying a retrieval state, ascending. A day absent from this list is \"none\"; the list is empty whenever invoice_state is \"none\", and is ALWAYS empty on a \"analysis\" call, which paints the categorization axis instead — so an empty list there carries no invoice claim."
  5. Changed10 schema fields changed
    • changedInput schema / properties / purpose / description
      Previous value: -"Why the months are being listed, set by the calling skill (not guessed from the user's words). \"close\" is book closure: the card paints close readiness, and each month carries its per-day `close_days` and the counts behind its \"why not ready\" errands. Omit or \"collect\" for invoice retrieval (the default), which paints the retrieval axis and skips the close-readiness fields."New value: +"Why the months are being listed, set by the calling skill's own flow — never inferred from this message. \"close\" is book closure: the card paints close readiness, and each month carries its per-day `close_days` and the counts behind its \"why not ready\" errands. \"analysis\" is reporting: the card offers only the months a canvas can report on, paints no day axis, counts on the execution date the canvas aggregates measure on, and therefore omits the books-dated errand counts entirely rather than reporting them as 0 — set it ONLY when a reporting skill is already running its own period-pick step, not just because this message names one (a burn figure, a cost breakdown, \"my report\"). Naming a report is phrasing; it never sets this field on its own. Omit or \"collect\" for invoice retrieval (the default, and the right choice for a plain \"what months do you have\" question, even one that mentions why) — this paints the retrieval axis and skips the close-readiness fields."
    • changedInput schema / properties / purpose / enum
      Previous value: -[
      -  "close",
      -  "collect"
      -]New value: +[
      +  "close",
      +  "collect",
      +  "analysis"
      +]
    • addedOutput schema / properties / periods / items / properties / analyzable
      Added value: +{
      +  "description": "The month can be REPORTED ON — an average-burn, cost-structure or cash-bridge figure can be computed for it. True once the month has ENDED and while it stays inside the window the canvas endpoints serve. Read this one for an analysis pick.",
      +  "type": "boolean"
      +}
    • changedOutput schema / properties / periods / items / properties / categorized_unposted_transactions / description
      Previous value: -"Categorized transactions not yet posted to the ledger — part of the 'review and book' close errand."New value: +"Categorized transactions not yet posted to the ledger — part of the 'review and book' close errand. Dated on the books, and likewise ABSENT rather than 0 on a \"analysis\" call."
    • changedOutput schema / properties / periods / items / properties / days / description
      Previous value: -"Days of the month carrying a retrieval state, ascending. A day absent from this list is \"none\"; the list is empty whenever invoice_state is \"none\"."New value: +"Days of the month carrying a retrieval state, ascending. A day absent from this list is \"none\"; the list is empty whenever invoice_state is \"none\", and is ALWAYS empty on a \"analysis\" call, which paints no day axis — so an empty list there carries no invoice claim."
    • addedOutput schema / properties / periods / items / properties / invoice_state / description
      Added value: +"The month's invoice-retrieval verdict. ABSENT on a month that has BEGUN and whose verdict nothing measured, which only a purpose counting on the execution date produces — its activity read and this books-dated errand disagree, so \"none\" there would be a claim nothing wrote. A month still ahead of today keeps \"none\" on every purpose, because it owes nothing on every basis. Read an absent one from a \"close\" or \"collect\" list."
    • changedOutput schema / properties / periods / items / properties / missing_invoice_count / description
      Previous value: -"Counterparties owing a supplier invoice for the month; 0 when invoice_state is none."New value: +"Counterparties owing a supplier invoice for the month; 0 when invoice_state is \"none\". Absent whenever invoice_state is, and for the same reason."
    • addedOutput schema / properties / periods / items / properties / transaction_count / description
      Added value: +"How many transactions the month holds, dated on the basis this purpose measures on: \"analysis\" counts on execution, every other purpose on the books. A presence signal for the month, never the row count behind a reported figure."
    • changedOutput schema / properties / periods / items / properties / uncategorized_transactions / description
      Previous value: -"Transactions in the month not yet categorized — the 'help categorize' close errand."New value: +"Transactions in the month not yet categorized — the 'help categorize' close errand. Dated on the books, so it is ABSENT on a \"analysis\" call rather than 0: that purpose counts on execution and never measures this errand."
    • changedOutput schema / properties / periods / items / required
      Previous value: -[
      -  "calendar_year",
      -  "calendar_month",
      -  "fiscal_year",
      -  "fiscal_period",
      -  "label",
      -  "is_complete",
      -  "selectable",
      -  "inspectable",
      -  "close_status",
      -  "close_reason",
      -  "invoice_state",
      -  "transaction_count",
      -  "bank_transaction_count",
      -  "unposted_invoice_count",
      -  "uncategorized_transactions",
      -  "categorized_unposted_transactions",
      -  "missing_invoice_count",
      -  "days"
      -]New value: +[
      +  "calendar_year",
      +  "calendar_month",
      +  "fiscal_year",
      +  "fiscal_period",
      +  "label",
      +  "is_complete",
      +  "selectable",
      +  "inspectable",
      +  "analyzable",
      +  "close_status",
      +  "close_reason",
      +  "transaction_count",
      +  "bank_transaction_count",
      +  "unposted_invoice_count",
      +  "days"
      +]
  6. Changed1 schema field changed
    • changedOutput schema / properties / periods / items / properties / inspectable / description
      Previous value: -"The month can be LOOKED INTO. A reader can open its transactions, missing invoices and days. True for the month in progress; every selectable month is also inspectable."New value: +"The month can be LOOKED INTO. A reader can open its transactions, missing invoices and days. True for every month that has begun, the month in progress included, whatever its close verdict and however little it holds. False only for a month that has not begun. Every selectable month is also inspectable."
  7. Changed4 schema fields changed
    • addedOutput schema / properties / periods / items / properties / bank_transaction_count
      Added value: +{
      +  "description": "The transaction_count subset delivered by a connector the workspace BANKS with, meaning its category is `banks` or its service id is on the bank-account list. An accounting platform and a payment processor deliver transactions too and are not counted. A transaction whose source connector is unknown, or since disconnected, is not counted either, so a 0 never licenses skipping a bank-connection step.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / periods / items / properties / inspectable
      Added value: +{
      +  "description": "The month can be LOOKED INTO. A reader can open its transactions, missing invoices and days. True for the month in progress; every selectable month is also inspectable.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / periods / items / properties / selectable / description
      Added value: +"The month can be CLOSED. False while it is still running."
    • changedOutput schema / properties / periods / items / required
      Previous value: -[
      -  "calendar_year",
      -  "calendar_month",
      -  "fiscal_year",
      -  "fiscal_period",
      -  "label",
      -  "is_complete",
      -  "selectable",
      -  "close_status",
      -  "close_reason",
      -  "invoice_state",
      -  "transaction_count",
      -  "unposted_invoice_count",
      -  "uncategorized_transactions",
      -  "categorized_unposted_transactions",
      -  "missing_invoice_count",
      -  "days"
      -]New value: +[
      +  "calendar_year",
      +  "calendar_month",
      +  "fiscal_year",
      +  "fiscal_period",
      +  "label",
      +  "is_complete",
      +  "selectable",
      +  "inspectable",
      +  "close_status",
      +  "close_reason",
      +  "invoice_state",
      +  "transaction_count",
      +  "bank_transaction_count",
      +  "unposted_invoice_count",
      +  "uncategorized_transactions",
      +  "categorized_unposted_transactions",
      +  "missing_invoice_count",
      +  "days"
      +]
  8. Changed11 schema fields changed
    • changedInput schema / properties / months / description
      Previous value: -"How many recent calendar months to return, ending with the current month. Each month holding activity costs one extra read for its invoice state."New value: +"How many recent calendar months to return, ending with the current month. Each month holding activity costs one extra read for its invoice state. Ignored when `year` is given."
    • addedInput schema / properties / purpose
      Added value: +{
      +  "description": "Why the months are being listed, set by the calling skill (not guessed from the user's words). \"close\" is book closure: the card paints close readiness, and each month carries its per-day `close_days` and the counts behind its \"why not ready\" errands. Omit or \"collect\" for invoice retrieval (the default), which paints the retrieval axis and skips the close-readiness fields.",
      +  "enum": [
      +    "close",
      +    "collect"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / workspace_id / description
      Previous value: -"Target workspace. Omit to use the only authorized workspace, or (for read tools) to query all authorized workspaces grouped by workspace. Required for write tools when the token authorizes more than one workspace."New value: +"Target workspace. This read reports one workspace's own data. Omit it and the token's primary workspace answers, which may not be the one you mean; the result names the workspace that did."
    • addedInput schema / properties / year
      Added value: +{
      +  "description": "One calendar year to return in full — all twelve of its months, December back to January, instead of the recent window. Use it to reach a year the recent window does not cover, in either direction; future months come back visible but never selectable. Accepted range: 2000-2100, also reported as `navigable_years`.",
      +  "maximum": 2100,
      +  "minimum": 2000,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / navigable_years
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The calendar years a `year` request is answered for. A picker's year steppers stop here.",
      +  "properties": {
      +    "earliest": {
      +      "type": "number"
      +    },
      +    "latest": {
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "earliest",
      +    "latest"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / periods / items / properties / categorized_unposted_transactions
      Added value: +{
      +  "description": "Categorized transactions not yet posted to the ledger — part of the 'review and book' close errand.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / periods / items / properties / close_days
      Added value: +{
      +  "description": "Days of the month carrying a non-neutral close-readiness state, ascending. Present ONLY for a \"close\" call; a day absent from it is \"neutral\" (nothing to close).",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "day": {
      +        "maximum": 31,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "state": {
      +        "enum": [
      +          "posted",
      +          "progress",
      +          "neutral"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "day",
      +      "state"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / periods / items / properties / uncategorized_transactions
      Added value: +{
      +  "description": "Transactions in the month not yet categorized — the 'help categorize' close errand.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / periods / items / required
      Previous value: -[
      -  "calendar_year",
      -  "calendar_month",
      -  "fiscal_year",
      -  "fiscal_period",
      -  "label",
      -  "is_complete",
      -  "selectable",
      -  "close_status",
      -  "close_reason",
      -  "invoice_state",
      -  "transaction_count",
      -  "unposted_invoice_count",
      -  "missing_invoice_count",
      -  "days"
      -]New value: +[
      +  "calendar_year",
      +  "calendar_month",
      +  "fiscal_year",
      +  "fiscal_period",
      +  "label",
      +  "is_complete",
      +  "selectable",
      +  "close_status",
      +  "close_reason",
      +  "invoice_state",
      +  "transaction_count",
      +  "unposted_invoice_count",
      +  "uncategorized_transactions",
      +  "categorized_unposted_transactions",
      +  "missing_invoice_count",
      +  "days"
      +]
    • addedOutput schema / properties / resolved_workspace
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The workspace that answered, when the caller named none and the token authorizes several.",
      +  "properties": {
      +    "name": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "workspace_id": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "workspace_id",
      +    "name"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "workspace_id",
      -  "fiscal_year_start_month",
      -  "base_currency",
      -  "periods",
      -  "default_period",
      -  "success"
      -]New value: +[
      +  "workspace_id",
      +  "fiscal_year_start_month",
      +  "base_currency",
      +  "periods",
      +  "default_period",
      +  "navigable_years",
      +  "success"
      +]
  9. Added

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds substantial behavioral context beyond that: the meaning of null vs absent values, the difference between transaction_count and bank_transaction_count, the caveat that `days` is empty for analysis calls, and the cost model of extra reads per month. It even explains future-month behavior, default_period fallback, and which fields are absent under `purpose: "analysis"`.

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

Conciseness3/5

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

The description is well sectioned with PURPOSE, WINDOW, and COST headings and is front-loaded with the core action, but it is extremely long and contains redundancy. For example, invoice_state and missing_invoice_count are introduced in the main bullet list and then revisited in a later bullet, and each day-axis variant (days, analysis_days, close_days) gets a lengthy exposition. It is structured, but it is not concise; many sentences could be trimmed without losing essential guidance.

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?

For a tool with 8 optional parameters, an output schema, and a rich domain, this description is comprehensively complete. It covers the picker's fields, the semantic traps (absent vs 0, selection vs analysis vs retrieval), the purpose-dependent behavior, the window options, cost implications, and even the necessary conversation/workspace context. Nothing needed for safe and correct invocation 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%, so the baseline is 3, but the description goes far beyond the schema. It explains when to use `year`, how `months` influences cost, how `purpose` should be set by the calling skill's flow and never inferred from user phrasing, the `reply` language requirement, and the `conversation_id` continuity rule. This adds real decision-making value for the agent.

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: 'List the recent accounting months of the workspace, with each month's close status, its invoice-retrieval state, and the counts that describe how much work it holds.' It also clearly distinguishes this listing tool from the many sibling list tools by focusing on the period picker and its field-level semantics.

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-use guidance: call this before any close, review, or month-scoped read; ask the user which month to work on; never guess or derive a month from today's date. It also explains when to pass `purpose: "close"`, `purpose: "analysis"`, or omit it for invoice retrieval, including the explicit note that a user merely mentioning a report is not the trigger for the analysis purpose.

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