A retainer is the easiest money to invoice and the easiest to forget. The amount does not change, the date does not move, and that is exactly why nobody notices when a month goes unbilled. MCP Recurring Invoices holds the schedule so you do not have to: client, line items, cadence, start date, terms. When you ask, it creates the invoices that have actually fallen due as real records in the invoice server, with its number series, its client list and its A4 PDF.
claude mcp add recurring -- npx -y @theluckystrike/mcp-recurring
{
"mcpServers": {
"recurring": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-recurring"]
}
}
}
The npm publish is pending, so until it lands use the .mcpb bundle from the latest
release or a clone and build; build servers/invoice first, because the engine is imported
from it. Per client paths are on the setup pages. Install the
invoice server too: this one has no business_set of its own on purpose, so there is exactly
one issuer profile to keep correct.
schedule_create {
client: "Acme Retainer", currency: "EUR", every: "monthly",
start_date: "2026-06-01", due_days: 14,
items: [{ description: "Retainer hours", quantity: 12, unit_price: 90 }]
}
-> schedule 9f2c1a04, next dates 2026-06-01, 2026-07-01, 2026-08-01, 2026-09-01
Cadences are weekly, monthly, quarterly, yearly or
{days: n}. Occurrence 0 is the start date itself, so a schedule starting today is due
today. end_date is inclusive: an occurrence landing exactly on it is generated and the next
one is not.
This is the part a naive date library gets wrong, and getting it wrong changes a client's payment
date permanently. The month step keeps the day of month of the start date and clamps it to the length of
the target month, and it never carries the clamp forward. From
2026-01-31 the series is 01-31, 02-28, 03-31, 04-30, 05-31.
The naive version adds one month to 31 January, lands on 28 February, and then adds one month to that,
so March becomes the 28th and every month after it does too. February silently turns a month-end
retainer into a 28th-of-the-month retainer, and nobody reads the invoice date closely enough to catch
it. The same rule makes a yearly schedule starting 2028-02-29 fall on 02-28 in common years
and back on 02-29 in the next leap year, because the anchor day is 29 throughout.
On Pro, anchor_day replaces the day of month before clamping, so
anchor_day: 31 means the last day of every month regardless of what the start date was, and
end_of_month: true says the same thing explicitly. Both are ignored for
weekly and {days: n}, which have no month to anchor to. An anchored first
occurrence that would land before the start date is dropped rather than billed early.
Here is the run that matters. On 3 September, against the schedule above:
invoice_generate_due {}
-> as_of 2026-09-03: created 4 invoices, skipped 0 already invoiced.
INV-2026-0001 period 2026-06-01 EUR 1080.00 due 2026-06-15
INV-2026-0002 period 2026-07-01 EUR 1080.00 due 2026-07-15
INV-2026-0003 period 2026-08-01 EUR 1080.00 due 2026-08-15
INV-2026-0004 period 2026-09-01 EUR 1080.00 due 2026-09-15
Total: EUR 4320.00
invoice_generate_due {} # five minutes later, having forgotten
-> as_of 2026-09-03: created 0 invoices, skipped 4 already invoiced.
The second call is the whole design. The key written to the history is
(schedule_id, period), not a timestamp and not the calendar day the run happened on. That
choice is what makes a billing run safe to repeat, safe to run from two clients, and safe to run after
a crash halfway through. Key it on the run date instead and a second run on a different day re-bills
everything; key it on the day and a run at 23:59 followed by one at 00:01 does the same. Because the
period is the key, "did I already bill September" is a question the data answers rather than one you
have to remember, and dry_run shows you the run before it happens.
The same key survives deletion. Deleting a schedule keeps its history rows deliberately, so a re-created schedule cannot double-bill a period that was already invoiced, and the tool warns when a new schedule's periods were covered by an old one.
A mistyped year is an ordinary typo. Before the cap existed, a schedule starting 1900-01-01 offered
1,520 due periods, and one call with as_of: "2126-01-01" on a plain monthly schedule
created 1,193 real invoices and 1,193 PDFs, 6.0 MB in 6.8 seconds, burning 1,193
numbers out of the shared invoice number series. Numbers are never reused, so that damage is permanent
in the sequence a tax authority reads. A run now stops at 60, oldest periods first, and the answer says
how many are still due. Idempotency is untouched by the cap, because the key is still the period: another
call simply continues.
Anything that writes an invoice takes the recurring lock first and the invoice lock second, always in that order, so a billing run and a hand-written invoice in the other server cannot interleave, cannot allocate the same number and cannot deadlock. Numbers are allocated inside the lock and the PDFs are rendered after it is released, so a slow render never holds up the counter.
One more thing worth knowing: if schedules.json or history.json is
unreadable, it is never treated as empty. The file is moved aside byte for byte, a marker is written and
every tool fails loudly until you restore it. A history file read as empty would re-bill every period
the schedule has ever covered, which is the worst failure this server could have.
Nothing runs in the background. This is a stdio MCP server: it exists while your client runs it.
There is no daemon, no cron and no email, so invoices appear when you ask for them, typically through
the monthly_billing_run prompt. Delivering the invoice and chasing payment are still yours;
overdue_report in the invoice server tells you who to chase. There is no proration, no
mid-period cancellation credit and no currency conversion.
Free gives 3 active schedules, unlimited generation, a 30 day upcoming view and a 3 month forecast.
Pro ($19 once) gives unlimited schedules, a 10 year horizon, a 120 month forecast, the
schedule_history audit log and the anchor day and end of month rules. Product page:
MCP Recurring Invoices. Side by side with the alternatives:
recurring billing comparison. The one-sentence invoice for everything
that is not on a retainer is in the invoice guide.
Nothing the second time. The history key is the schedule id plus the period, not the run date, so a repeated run reports created 0, skipped 4. That is what makes it safe to run from two clients, after a crash, or when you cannot remember whether you already did it.
It bills on 28 February, then back on 31 March. The month step keeps the start date's day of month and clamps it to the target month's length without carrying the clamp forward, so February does not permanently move a month-end retainer to the 28th.
No. It creates the invoice record and renders the PDF into the invoice server's store. Delivery and chasing are yours; overdue_report in the invoice server lists who is late.
Into the invoice server's own data directory, with the PDFs in its pdf subfolder, so they appear in invoice_list, count in overdue_report and can be re-rendered with invoice_pdf. Both servers must see the same XDG_DATA_HOME or you end up with two stores.
Not any more. A run is capped at 60 periods, oldest first, and says how many remain. Before the cap, one call with a mistyped as_of year created 1,193 invoices and PDFs and burned 1,193 numbers out of a series that never reuses one.