Skip to main content
Glama
theluckystrike

dunning-letters

mcp-dunning-letters

MCP server for dunning letters and overdue invoice payment reminders: reminder, final notice and aging. Chase overdue invoices on a ladder anchored to the due date: reminder 1, reminder 2, the final notice, with the aging and the day's chase list.

Works with Claude Desktop, Claude Code, Cursor and any Model Context Protocol client. Runs on your own machine, or hosted with no install.

Install

Hosted, nothing to install. Get a token from https://mcp.zovo.one/mcp/connect (the connect page) or https://mcp.zovo.one/mcp/token (the same token as JSON); a free anonymous one is issued on the spot and a Pro key works the same way. Then point an MCP client at https://mcp.zovo.one/mcp/dunning-letters over streamable-http and send the token as Authorization: Bearer <token>.

If your client cannot set headers, put the token in the path instead: https://mcp.zovo.one/mcp/dunning-letters/t/<token>. Both forms work. The bare URL with no token answers 401 on tools/call, so the token is not optional.

Claude Desktop, one click. Download dunning-letters.mcpb from the latest release and double-click it.

From source. The mirror is self-contained: every @theluckystrike/* dependency is vendored, so a fresh clone builds with no extra setup.

git clone https://github.com/theluckystrike/mcp-dunning-letters.git
cd mcp-dunning-letters
npm install && npm run build

Then point your client at the built entry point:

{
  "mcpServers": {
    "dunning-letters": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-dunning-letters/dist/index.js"]
    }
  }
}

@theluckystrike/mcp-dunning-letters is not published on npm yet, so an npx -y @theluckystrike/mcp-dunning-letters command will fail. The three paths above are the working ones and each is exercised by CI.

dunning-letters demo

Read-only mirror of mcp-servers/servers/dunning-letters. See MIRROR.md.

In the official MCP Registry (io.github.theluckystrike/dunning-letters). Chase overdue invoices without losing the thread. Register an unpaid invoice -- client, invoice reference, amount in integer cents, currency, due date -- and the server runs the escalation ladder: reminder 1 (polite, due + 7 days), reminder 2 (firm, with the late fees note, due + 14), and the final notice (before-action wording, due + 21; the gaps are configurable per invoice). For each stage it generates the letter, as Markdown or as a self-contained printable HTML page. It records what you sent and when, lists everything overdue with days late and stage, ages the whole register into current/30/60/90+ buckets, and answers "what do I need to send today". Nothing is emailed or sent anywhere: this server produces the letter text, and sending it is your act.

Built by theluckystrike.

npm publish for @theluckystrike/mcp-dunning-letters is pending, so npx -y @theluckystrike/mcp-dunning-letters returns 404 today. Until then, a clone+build is the working path.

Related MCP server: mcp-statement-of-account

Install

Claude Desktop

macOS ~/Library/Application Support/Claude/claude_desktop_config.json, Windows %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "dunning-letters": {
      "command": "npx",
      "args": ["-y", "@theluckystrike/mcp-dunning-letters"]
    }
  }
}

Claude Code

claude mcp add dunning-letters -- npx -y @theluckystrike/mcp-dunning-letters

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (project), same entry as Claude Desktop.

Tools

tool

what it does

invoice_register

Start chasing an unpaid invoice: client, reference, amount, currency, due date. Returns DUN-YYYY-NNNN and the three escalation dates

payment_record

Record money received, full or partial. A part payment lowers what the next letter asks for; covering the balance closes the ladder

letter_render

Generate the chase letter for the current stage -- reminder 1, reminder 2 or the final notice -- as Markdown or self-contained printable HTML. Nothing is emailed: you send the text it produces

letter_sent

Record that a letter actually went out, with its date, so the ladder advances. Letters go out in order

overdue_list

Every unpaid invoice past its due date: days late, outstanding, letters sent, what is due next, worst first

aging_summary

The whole register in current/1-30/31-60/61-90/91+ buckets, counts and totals in integer cents, per currency

chase_today

The day's chase list: which invoices cross an escalation threshold today, which letter to send each, what falls due next

invoice_status

One chased invoice in full: payments, letters, schedule, next action

invoice_delete

Delete an invoice entered wrongly. The id is not reissued

license_status / license_activate

Free or Pro, and the key

Free vs Pro

Free

Pro

Unpaid invoices chased at once

3

Unlimited

All three letters, both formats

Yes

Yes

Aging summary and the day's chase list

Yes

Yes

Late fee accrual in the letters

Yes

Yes

Payment recording and history

Yes

Yes

The cap is on how many chases run at once, never on the letters or the aging: three late payers taken from first reminder to final notice is a real chase list, and an invoice that gets paid frees its slot. What is metered is breadth -- a fourth concurrent chase is a collections workload, not a freelancer's month.

Get Pro: https://mcp.zovo.one/buy/dunning-letters -- $19 one-time for this server, or $39 for the bundle.

A measured insight

The ladder is anchored to the due date, not to the last letter, and the two drift apart exactly when chasing is going badly.

The worked chase in test/_client.mjs: USD 1,250.00 due 2026-06-01, gaps 7/14/21, so the letters fall due on 06-08, 06-15 and 06-22 whether or not anything was sent. If reminder 1 actually goes out late -- say 06-20, twelve days after its date -- a previous-letter-anchored ladder would push the final notice to 07-11. This one does not: 06-22 stands, because the client's obligation was fixed by the due date, not by when you got around to writing. Recording a sending moves only which stage is next; it never moves the schedule. The letters are also strictly sequential: an invoice 60 days late with nothing sent is still owed reminder 1, because a final notice that no polite letter preceded reads as a threat, not a chase.

The late fee is measured the same way, once: simple interest, pro-rata on a 30-day month, on the amount outstanding on the day the letter is written, rounded once to the minor unit. On the worked chase that is 125,000 minor units at 2% over 30 days late -- 2,500 exactly -- and after a 50,000 part payment it is 1,500 on the 75,000 that remains, so the final notice asks for 76,500 and no invented figure more.

Privacy

All data stays local, in ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/dunning-letters/. Two files: invoices.json, counter.json. Nothing is sent anywhere -- no account, no API key, no network call in this server at all -- and the letters are rendered to text for you to send yourself; this server holds no mail credentials and wants none. License keys are verified offline.

Built by theluckystrike. https://github.com/theluckystrike

Available Tools

11 tools
aging_summaryAging summary of what is owedA

The aging summary across every unpaid invoice: current, 1-30, 31-60, 61-90 and 91+ day buckets, with counts and totals in integer cents, per currency. This is the answer to "how much am I owed, and how stale is it".

ParametersJSON Schema
NameRequiredDescriptionDefault
onNoThe date to age against, YYYY-MM-DD. Default today

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the full disclosure burden, and it does real work: it scopes the result to unpaid invoices only, defines the bucket boundaries, specifies units as integer cents, and notes grouping per currency. It stops short of stating read-only safety or whether it aggregates across all entities with no filtering.

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

Conciseness5/5

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

Two sentences, zero filler: the first sentence front-loads the payload and its exact dimensions, the second gives the use case. Everything earns its place.

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

Completeness4/5

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

Despite having no output schema and no annotations, the description defines the bucket structure, units, and grouping well enough for an agent to know what comes back. Only the aging-date behavior (how 'on' reshapes buckets) and read-only nature are left unaddressed.

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% and the single 'on' parameter is fully documented in the schema (YYYY-MM-DD, default today). The description adds no extra meaning about the aging date or how buckets shift relative to it, so the baseline 3 applies.

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

Purpose4/5

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

The description names a specific artifact (aging summary across every unpaid invoice) and enumerates the exact buckets it produces, so the resource is unambiguous. It does not explicitly carve itself apart from close siblings like overdue_list or invoice_status, so the differentiation is left to inference rather than stated.

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

Usage Guidelines3/5

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

The framing line 'the answer to "how much am I owed, and how stale is it"' implies the use case but never states when to pick this over overdue_list or invoice_status, nor any exclusions or prerequisites. Usage is implied, not guided.

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

chase_todayWhat to chase todayA

The day's chase list: which invoices cross an escalation threshold today, which letter to send each and how long it has been waiting, what falls due in the next few days, and which invoices have had all three letters and need a decision outside this server.

ParametersJSON Schema
NameRequiredDescriptionDefault
onNoThe date to run the list for, YYYY-MM-DD, e.g. to see what Monday will need. Default today
within_daysNoHow far ahead to list letters coming due, default 7 days

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the full load and does disclose meaningful behaviour: it is an advisory listing (it says which letter to send, not that it sends one) and it explicitly flags the boundary case of invoices that fall outside the server's capability. It stops short of stating read-only status, side effects, or permission requirements.

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?

A single dense sentence that front-loads the purpose and then lists four distinct output categories, with no filler. It is a long clause chain that could be split for scanability, but every clause carries information.

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

Completeness4/5

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

With no output schema, the description must describe what comes back, and it does so concretely across all four result categories while implicitly covering both inputs. It omits read-only/mutation status and result shape details, which is the remaining gap for a two-parameter report tool.

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% and both parameters are optional and fully documented in the schema (including the 'see what Monday will need' example and the default). The description adds only the loose mapping of "what falls due in the next few days" to within_days, so the baseline 3 applies.

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

Purpose4/5

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

The description enumerates exactly what the tool produces: today's escalation-crossing invoices, the letter recommended for each and its waiting time, upcoming due items, and fully-lettered invoices needing an out-of-server decision. That is far more specific than the title alone, though it never names a sibling (overdue_list, aging_summary) to draw the boundary.

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

Usage Guidelines3/5

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

Usage is implied by "The day's chase list" and by the note that exhausted cases "need a decision outside this server," which quietly tells the agent when this tool is not the answer. There is no explicit statement of when to prefer it over overdue_list or aging_summary, so the guidance remains inferential.

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

invoice_deleteDelete an invoice from the registerA

Delete an invoice entered wrongly, by id or reference: the record, its payments and its letter history. The id is not reissued, so a gap in the DUN series is the record that a deletion happened.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoiceYesThe chased invoice: its id (DUN-2026-0001) or its invoice reference

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does substantial work: it discloses the cascade (record, payments and letter history all removed), the permanence of the id, and the observable side effect of a DUN series gap. It stops short of stating auth requirements, reversibility, or failure behavior.

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?

Front-loaded with the verb and identifier, and the destructive scope is stated immediately after. The trailing sentence about the DUN series gap is a bit indirect but is genuinely informative rather than filler.

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

Completeness4/5

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

For a one-parameter destructive tool with no annotations and no output schema, the key things an agent must know (what gets removed, that it is permanent) are covered. Auth/permission requirements and error handling remain unstated, a minor gap.

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% for the single parameter, and the schema already documents both id format (DUN-2026-0001) and reference. The description adds only the same id-or-reference duality, so it earns the baseline 3 rather than more.

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

Purpose4/5

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

States a specific verb (delete) and resource (invoice) plus the accepted identifiers (id or reference). It is clearly distinct from the sibling read tools like invoice_register and invoice_status, though it never names an alternative tool explicitly.

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

Usage Guidelines3/5

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

"Delete an invoice entered wrongly" implies the intended use case (correcting a mistaken entry), which is useful framing. However there is no explicit when-not guidance, no prerequisites, and no mention of any alternative remedy for a bad invoice.

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

invoice_registerRegister an unpaid invoice to chaseA

Start chasing an unpaid invoice: register the client, the invoice reference, the amount in integer cents, the currency and the due date, and get the three-letter escalation schedule (reminder 1, reminder 2, final notice) with the date each falls due. Free tier: 3 unpaid invoices chased at once.

ParametersJSON Schema
NameRequiredDescriptionDefault
dueYesThe date payment fell due, YYYY-MM-DD. The ladder is anchored to this date
gapsNoDays after the due date at which reminder 1, reminder 2 and the final notice fall due, strictly increasing. Default [7, 14, 21]
noteNo
clientYesWho owes the money, e.g. Acme Ltd
issuedNoThe date the invoice was issued, YYYY-MM-DD, for the letter's reference line
currencyYesISO code the invoice was issued in
referenceYesThe invoice number being chased, e.g. INV-1042
amount_minorYesThe invoice amount in whole minor units (integer cents). 125000 is USD 1,250.00
duplicate_okNoRegister even though an identical invoice is already on the register. Default false
late_fee_percent_per_monthNoLate payment interest your terms allow, percent per month, simple and pro-rata. When set, reminder 2 and the final notice state the accrued figure

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It usefully discloses the return shape (reminder 1/2/final notice with due dates) and a quota (free tier: 3 concurrent invoices), but says nothing about permissions, idempotency, or what happens when a duplicate invoice is already on the register.

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?

Two sentences, front-loaded with the action and outcome, then the tier constraint. Slightly wasteful in re-listing the required parameters that the schema already names, but no fluff overall.

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

Completeness4/5

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

For a 10-parameter mutation tool with no annotations and no output schema, the description compensates well by explaining what is returned (the escalation ladder and its dates). Gaps remain around duplicate handling and permissions, but the core call-and-result picture is complete.

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 90%, so the schema already documents fields like amount_minor, currency, due and gaps. The description only restates 'amount in integer cents' and the field list, adding no meaning beyond the schema; baseline 3 applies.

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

Purpose4/5

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

The description states a specific verb (register) and resource (an unpaid invoice) and specifies the concrete payoff: a three-step escalation schedule with dates. It is clearly distinguishable from read-only siblings like invoice_status or overdue_list, but it never names an alternative tool, so it stops short of full sibling differentiation.

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

Usage Guidelines3/5

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

'Start chasing an unpaid invoice' implies the trigger condition, and the free-tier limit (3 concurrent unpaid invoices) is a real usage constraint. However, there is no guidance on alternatives (e.g. invoice_status, chase_today) or on prerequisites such as what to do when the invoice is already registered.

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

invoice_statusThe full state of one chased invoiceA

One chased invoice in full: what was billed, what has been paid and what is still owed, every letter sent with its date, the escalation schedule with each stage's state, and what happens next and when.

ParametersJSON Schema
NameRequiredDescriptionDefault
onNoThe date to judge lateness against, YYYY-MM-DD. Default today
invoiceYesThe chased invoice: its id (DUN-2026-0001) or its invoice reference

TDQS

A3.7/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses the returned content in useful detail — payment state, each letter with its date, escalation stages and their individual states, and the next action with timing — which tells an agent what to expect from a read. It stops short of stating that the call is read-only or what happens for an unknown invoice reference.

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?

A single front-loaded sentence opens with the scope ('one chased invoice in full') and then enumerates the payload. It reads as a long run-on list, but every clause describes distinct returned content, so little is wasted.

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

Completeness4/5

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

There is no output schema, so the description must convey the return shape, and it does so thoroughly (amounts, letters, escalation schedule, next action). With parameters fully documented in the schema and only two of them, the definition is nearly complete; only read-only status and error behavior are unstated.

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% and both parameters carry their own format guidance (invoice id vs. reference, the 'on' date with default today), so the schema does the heavy lifting. The description adds nothing about parameters, which is the expected baseline when coverage is complete.

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

Purpose4/5

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

The description states a specific resource ('one chased invoice in full') and enumerates exactly what state it reports — billed, paid, owed, letters, escalation schedule. The word 'one' implicitly separates it from the list-oriented siblings (overdue_list, aging_summary, invoice_register), but no sibling is named, so it stops short of a 5.

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

Usage Guidelines3/5

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

Usage is only implied: the phrase 'one chased invoice' signals a single-invoice lookup rather than an aggregate view, which is the natural alternative among the siblings. There is no explicit when-to-use, no named alternative, and no stated prerequisites or exclusion conditions.

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

letter_renderGenerate the chase letter for the current stageA

Chase an unpaid invoice: generate the letter for the current stage of the ladder -- reminder 1 (polite), reminder 2 (firm, with the late fees note) or the final notice (before-action wording) -- as Markdown or as self-contained printable HTML. Nothing is emailed or sent anywhere: this server produces the letter text, and sending it is your act. Record the sending with letter_sent so the ladder advances.

ParametersJSON Schema
NameRequiredDescriptionDefault
onNoThe letter's date, YYYY-MM-DD; late fees accrue to it and the final-notice deadline is 7 days after it. Default today
stageNoRender a specific stage instead of the one currently due, to preview or to re-issue a letter already sent
formatNomarkdown (default) or html: a self-contained printable page with no external anything
invoiceYesThe chased invoice: its id (DUN-2026-0001) or its invoice reference

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does the most important thing: it disproves the obvious assumption that this tool sends the letter ('Nothing is emailed or sent anywhere... sending it is your act'). It also hints at ladder state advancement. It does not cover error behavior or whether re-issuing a sent letter has side effects.

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?

Two sentences and every clause earns its place, with the core action front-loaded. The dense em-dash parenthetical in the first sentence slightly hurts scanability, but nothing is redundant.

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?

No output schema, and the description covers what an agent needs: what is produced (letter text in Markdown or printable HTML), that nothing is transmitted, how to act on it (letter_sent), plus stage/date/format semantics. Nothing material is missing for a rendering 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?

Schema coverage is 100%, so a 3 is the baseline, but the description adds real meaning: it explains what each stage value produces ('reminder 1 polite, reminder 2 firm with the late fees note, final notice before-action wording') and that html is 'self-contained printable,' which the enum labels alone do not convey.

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?

States a specific verb and resource ('generate the letter for the current stage of the ladder') and enumerates the three stage variants, so an agent can distinguish it from letter_sent, chase_today, and aging_summary without opening any schema.

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?

Gives the triggering condition (chasing an unpaid invoice at the currently-due stage), an override condition for the stage param ('to preview or to re-issue a letter already sent'), and routes the follow-up action explicitly: 'Record the sending with letter_sent so the ladder advances.'

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

letter_sentRecord that a letter was sentA

Record that a chase letter was actually sent, with its date, so the ladder advances to the next stage. Letters go out in order: reminder 2 cannot be recorded before reminder 1. Returns what is due next and when.

ParametersJSON Schema
NameRequiredDescriptionDefault
sentNoThe date it was sent, YYYY-MM-DD. Default today
stageNoWhich letter went out. Default the lowest unsent stage
invoiceYesThe chased invoice: its id (DUN-2026-0001) or its invoice reference

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does well: it discloses the mutation's side effect (ladder advances), a validation ordering rule that can cause rejection, and the return content ('what is due next and when') despite there being no output schema. It omits any mention of permissions or what happens on out-of-order or duplicate submissions.

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

Conciseness5/5

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

Three short sentences, front-loaded with the action and effect, then the ordering rule, then the return value. Nothing is redundant or padded.

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

Completeness4/5

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

For a 3-parameter mutation with no annotations and no output schema, the description supplies effect, ordering validation, and even the return payload, so an agent can invoke it correctly. Minor gaps remain around error/permission behavior on invalid submissions.

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 'sent' (YYYY-MM-DD, default today), 'stage' (enum 1-3, default lowest unsent) and 'invoice' (id or reference) are already fully documented. The description only broadly restates the date and hints at the stage ordering, adding little beyond the schema — baseline 3.

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?

States a specific verb+resource (record a chase letter as sent) and its effect (advances the dunning ladder). It is clearly distinguished from the sibling letter_render, which produces the letter rather than recording it.

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

Usage Guidelines4/5

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

Establishes the triggering condition (the letter was 'actually sent') and gives an explicit ordering constraint: reminder 2 cannot be recorded before reminder 1. It does not name letter_render or other siblings as the alternative for the 'generate the letter' path, so routing is left partly to inference.

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

license_activateActivate licenseA

Activate a Pro key (MCPL1.xxx.yyy) from checkout: verified offline against a built-in public key, saved to your config file. A wrong, malformed or expired key is refused, unsaved. license_status reads it back.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesLicense key from the checkout confirmation page

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral burden. It discloses that verification happens offline against a built-in public key, that the key is persisted to the config file, and that invalid keys are refused and left unsaved. This is substantial transparency for an activation tool, though it could mention overwriting an existing key or the exact return behavior.

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

Conciseness5/5

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

The description is two sentences with no filler. The first sentence front-loads the main action, source, verification method, and persistence. The second sentence efficiently covers error handling and points to the related read-back tool. Every clause adds value.

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

Completeness4/5

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

Given a single-parameter tool with no output schema and no annotations, the description covers activation behavior, verification mechanism, persistence, error outcomes, and how to read the result later. The only minor gap is an explicit statement of what the function returns upon success or failure, but the phrase 'refused, unsaved' implies a feedback mechanism. Overall, it is sufficiently complete for an agent to call it correctly.

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 documents the 'key' parameter at 100% coverage, so the baseline is 3. The description adds meaningful semantics by giving the concrete key format ('MCPL1.xxx.yyy'), confirming the key comes from the checkout page, and explaining that malformed or expired keys will be rejected. This goes beyond the schema's one-line description.

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 action ('Activate a Pro key'), the exact key format ('MCPL1.xxx.yyy'), the source ('from checkout'), and the core mechanism ('verified offline against a built-in public key'). It also differentiates itself from the sibling license_status by noting that license_status reads the activation back, so there is no ambiguity about which tool does what.

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

Usage Guidelines4/5

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

The description gives clear context: use this when you have a Pro key from checkout that needs to be activated. It also points to license_status as the read-back tool, which implies when to use a related sibling. It does not explicitly spell out 'do not use for checking status' or list other alternatives, but the context is strong enough to avoid misuse.

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

license_statusLicense statusA

Report this server's licence state: product, tier free or pro, licence id, expiry, the key source and the upgrade URL. No arguments, no network. Explains a free-tier refusal; license_activate installs a key.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations are absent, so the description carries the full burden of behavioral disclosure. It discloses that the call is local ('no network') and argument-free, and it mentions a specific explanatory behavior. The word 'Report' implies read-only, though it does not explicitly state non-destructive or permission requirements; this is adequate for a status command.

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

Conciseness5/5

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

Two sentences with no filler. The first sentence lists the output fields; the second adds constraints and the sibling pointer. Every clause contributes meaningful information.

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 zero-parameter status tool with no output schema, the description lists the expected output fields, behavioral constraints, and the relevant alternative tool. Nothing an agent needs to call it correctly is missing.

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 has zero parameters and the description reinforces this with 'No arguments'. It adds value by listing the reported fields, helping an agent understand what the empty input will yield. The baseline for zero-parameter tools is high, and the description meets it.

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 ('Report'), a clear resource ('this server's licence state'), and enumerates the exact fields returned. It also names the sibling 'license_activate' as the tool that does something different, so an agent can distinguish them immediately.

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 usage constraints: no arguments, no network, and explains a free-tier refusal. It also directs the agent to license_activate when the task is to install a key, serving as an explicit pointer to the relevant alternative.

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

overdue_listList overdue invoicesA

Every unpaid invoice past its due date: how many days late, what is still owed, which letters have gone out, and what is due next and when. Sorted by days late, worst first.

ParametersJSON Schema
NameRequiredDescriptionDefault
onNoThe date to judge lateness against, YYYY-MM-DD. Default today
limitNoMaximum rows, default and ceiling 2000

TDQS

A3.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it does meaningful work: it discloses the derived fields returned (days late, amount owed, letters sent, next due date) and the sort order (days late, worst first). Read-only nature is only implied by 'list', and permissions/limits/rate behavior are unaddressed, so not a 5.

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?

A single dense sentence with the scope front-loaded and a trailing clause on ordering; there is no filler. The clause 'what is due next and when' is slightly loose, keeping it just short of a 5.

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

Completeness4/5

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

For a read-only list tool with no output schema and no annotations, the description compensates well by describing the shape and ordering of results. It leaves minor gaps around the as-of date semantics and the 2000-row default/ceiling, but those live in the schema.

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 both parameters (as-of date and row limit) are already documented in the schema. The description adds nothing parameter-specific — notably it never mentions that lateness is judged against a caller-supplied date — so the baseline 3 applies.

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

Purpose4/5

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

The description gives a specific verb/resource (list unpaid invoices past due date) and enumerates the returned fields, so an agent knows exactly what it produces. It does not, however, distinguish itself from close siblings like aging_summary or chase_today, so a 4 rather than a 5.

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

Usage Guidelines2/5

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

There is no explicit when-to-use guidance, no exclusions, and no naming of alternatives such as aging_summary (aggregate view) or chase_today (action on today's chases). Scope is implied by the field list, but the agent gets no routing help for a crowded sibling set.

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

payment_recordRecord a payment receivedA

Record money received against a chased invoice, in whole MINOR units: a part payment lowers what is still chased, a payment that covers the balance closes the ladder and frees the free-tier slot. Returns the outstanding amount.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoThe date the money arrived, YYYY-MM-DD. Default today
noteNoHow it was paid, e.g. Bank transfer, or what it was against
invoiceYesThe chased invoice: its id (DUN-2026-0001) or its invoice reference
amount_minorYesWhat was received, in whole minor units

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses that a partial payment reduces the outstanding chased amount, that a covering payment closes the invoice and frees the free-tier slot, and that the return value is the outstanding amount. It omits permissions, idempotency/duplicate handling, and which currency the minor units belong to.

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?

A single front-loaded sentence leads with the action and then packs the two key consequences efficiently. The domain shorthand ('closes the ladder', 'frees the free-tier slot') is slightly jargon-heavy but still parses without prior context.

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

Completeness4/5

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

For a mutation tool with no annotations and no output schema, the description covers the essential state change and the return value ('outstanding amount'). It is nearly complete, missing only permission requirements, idempotency behavior, and overpayment handling.

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 all four parameters are already documented, making 3 the baseline. The description adds only the semantic effect of amount_minor (partial vs. covering payment) and repeats the 'whole MINOR units' convention already in the schema; date, note, and invoice semantics are left entirely to the schema.

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

Purpose4/5

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

The description gives a precise verb+resource ('Record money received against a chased invoice') and specifies the unit convention, so the operation is unambiguous. It stops short of contrasting itself with siblings such as invoice_register or invoice_status, so it does not reach the sibling-differentiation bar for a 5.

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

Usage Guidelines3/5

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

Usage is only implied by the phrase 'against a chased invoice' – the agent can infer this applies when money arrives for an outstanding chased invoice, but there is no explicit when-to-use, when-not, or named alternative. No guidance is given on duplicate payments or what happens if the amount exceeds the balance.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv0.22.0
    • First observedaging_summary
    • First observedchase_today
    • First observedinvoice_delete
    • First observedinvoice_register
    • First observedinvoice_status
    • First observedletter_render
    • First observedletter_sent
    • First observedlicense_activate
    • First observedlicense_status
    • First observedoverdue_list
    • First observedpayment_record

TDQS

A4.1/5.0

Scored across 11 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: registration, payments, letter generation, recording sent letters, status queries, reporting, and license management. Even the reporting tools (overdue_list, aging_summary, chase_today) target different views (detailed list, summary buckets, today's actions) with descriptions that prevent confusion.

Naming Consistency4/5

All tool names use snake_case and mostly follow a noun-verb or verb-noun pattern, but the order is inconsistent (e.g., invoice_register vs. payment_record). Some names are noun-noun (license_status, aging_summary) or ambiguous (chase_today). Despite this, the pattern is readable and predictable enough.

Tool Count5/5

With 11 tools, the set is well-scoped for the domain. It covers the core invoice lifecycle (register, status, delete), payment handling, letter generation and sending, comprehensive reporting (overdue, aging, daily chase), and license management. Each tool earns its place.

Completeness5/5

The tool surface is complete for dunning letter management: starting chases, recording payments, generating and tracking letters, querying invoice state, and producing aggregated reports. The license tools are separate but necessary. No obvious gaps in the lifecycle are apparent.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    AI-powered invoice automation. Create PDF invoices, predict late payment risk 0-100, auto-send reminders, reconcile Stripe/PayPal payments, track cash flow. 10 MCP tools, 4 resources.
    10
    37 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables building client statements of account from existing invoices, credit notes, and deposits, with aged outstanding balances, PDF/plain-text output, and drafted payment chasers at friendly, firm, or final levels.
    8
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP clients to search and inspect an invoice ledger, generate VAT summaries, run OCR on local documents, and use reusable prompts for chasing overdue invoices and reconciling entries.
    2
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Lets a user ask what their business is owed, who to chase first, and get a chase email drafted in their own voice, via tools for weekly totals, chase queues, customer history, due-soon invoices and insights. Every tool only reads or returns a draft, so nothing can be sent.
    MIT