mcp-statement-of-account
This server builds customer statements of account, ages what is overdue, and drafts payment chasers from your existing invoice, credit-note and deposit ledgers.
statement_build: produce one client's statement for a period (opening balance, invoices, payments, credit notes, deposits applied, closing balance) in minor units.statement_aging: age open invoices into 0-30, 31-60, 61-90, and 90+ days past due as at any date, per client and/or currency.statement_text: get the statement as a plain-text letter ready to paste into an email.statement_pdf: render an A4 PDF statement titled STATEMENT OF ACCOUNT (Pro).dunning_text: write a friendly, firm, or final-demand payment chaser, listing overdue invoices and bank details; refused if nothing is overdue.statements_report: see a receivables roll-up across every client—totals, aging, clients ranked by overdue amount, oldest overdue invoice (Pro).license_status/license_activate: check or activate a Pro license key offline.Also exposes a
statement://sourcesresource describing the three data stores and achase_overdueprompt.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-statement-of-account Build a statement of account for Acme Corp for last month as a PDF."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-statement-of-account
MCP server for customer statements of account, accounts receivable and invoice aging. The one document that answers what a client actually owes you, aged as at any date, with the chaser drafted.
Works with Claude Desktop, Claude Code, Cursor and any Model Context Protocol client. Runs on your own machine, or hosted with no install.
Product page: https://mcp.zovo.one/s/statement-of-account — what it does, the tools it exposes, and a live token endpoint.
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/statement-of-account 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/statement-of-account/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 statement-of-account.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-statement-of-account.git
cd mcp-statement-of-account
npm install && npm run buildThen point your client at the built entry point:
{
"mcpServers": {
"statement-of-account": {
"command": "node",
"args": ["/absolute/path/to/mcp-statement-of-account/dist/index.js"]
}
}
}
@theluckystrike/mcp-statement-of-accountis not published on npm yet, so annpx -y @theluckystrike/mcp-statement-of-accountcommand will fail. The three paths above are the working ones and each is exercised by CI.

Read-only mirror of mcp-servers/servers/statement-of-account. See MIRROR.md.
In the official MCP Registry (io.github.theluckystrike/statement-of-account).
Send a client the one document that answers "what do I actually owe you". This MCP server
reads the books you already keep in this suite, your invoices, your credit notes and your
deposits, and turns them into a statement of account for a period: the balance you were
carrying at the start, every invoice you issued, every payment that came in, every credit
note you gave, and the balance at the end. It ages what is still open into 0-30, 31-60,
61-90 and over 90 days past due, so you can see at a glance which client is the problem;
it writes the statement as pasteable text or as an A4 PDF that looks like your invoices;
and it drafts the chaser, at a friendly, a firm or a final level. It never writes anything
back into your invoices, and it never invents a late fee.
Built by theluckystrike.
npm publish for @theluckystrike/mcp-statement-of-account is pending, so npx -y @theluckystrike/mcp-statement-of-account returns 404 today. Until then, the .mcpb one-click bundle or a clone+build is the working path.
Related MCP server: kelo-mcp
Install
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or
%APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"statement-of-account": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-statement-of-account"]
}
}
}Claude Code
claude mcp add statement-of-account -- npx -y @theluckystrike/mcp-statement-of-accountCursor
~/.cursor/mcp.json (global) or .cursor/mcp.json (project), same entry as Claude Desktop.
Tools
tool | what it does |
| One client's statement for a period: opening balance, invoices issued, payments received, credit notes, deposits applied, closing balance. Every figure in minor units and formatted |
| What is owed, split into 0-30, 31-60, 61-90 and over 90 days past the due date as at a chosen date, for one client or for everyone, per currency |
| The same statement as plain text, movements in date order, ready to paste into an email |
| The same statement as an A4 PDF titled STATEMENT OF ACCOUNT, on the same page layout as your invoices and credit notes |
| A payment chaser at level 1 (friendly), 2 (firm) or 3 (final demand), with the overdue list and your bank details |
| Every client at once: what is outstanding per currency, aged, and the oldest overdue invoice in the book |
| Free or Pro, and where to upgrade |
| Activate a Pro key |
Plus the statement://sources resource, which says which of the three stores this server
could read and how many rows each holds, and the chase_overdue prompt.
Free vs Pro
Free | Pro | |
Statements built | 5 a calendar month | unlimited |
Rebuilding a statement already built | unlimited | unlimited |
| unlimited | unlimited |
| yes | yes |
| yes | yes |
| no | yes |
| no | yes |
| no | yes |
PDF footer credit | shown | removed |
Aging is free and unlimited on purpose. "Who owes me money" is the question this whole server exists for, and a free tier that hides it is a demo rather than a tool. The meter is on the statement, the document that actually goes to a client, and it counts distinct statements: the same client, period and currency built again is free forever.
Get Pro, one-time, lifetime, for this server. Keys verify offline.
Where the numbers come from
Nothing here is typed in twice. The server reads three stores and writes to none of them:
store | server | what is taken from it |
|
| the invoices, their due dates and how much of each is paid |
|
| the credit notes, already stored with a negative sign |
|
| the deposit applications, and what is still held |
A store you have never installed is simply absent, and the statement is built without it. A store that is on disk and cannot be READ is a different thing entirely, and is reported as such on every figure, because a balance that could not be computed must never be shown as a balance of nothing owed. The one store the server refuses to work without is the invoice ledger.
A measured insight
Aging a past date with today's payment figures is not slightly wrong, it is silently
empty. Aging is usually written as "take each invoice, subtract what has been paid, and
bucket by the due date". The subtraction is the part nobody dates. On the worked month in
test/_client.mjs, aged at 2026-06-10, the two rules give:
rule | outstanding | overdue |
as at 2026-06-10 | 2,500.00 EUR | 500.00 EUR, 31 days late |
today's | 1,700.00 EUR | 0.00 EUR |
The naive rule understates what was owed by 800.00 of 2,500.00, a third of the balance,
and it reports NOTHING overdue on a date when an invoice was a month late, because a
payment that arrived two days later has already been subtracted from it. The failure is
invisible: the answer looks tidy, the buckets add up, and it cannot be reproduced next
month because the input keeps moving. So every figure in statement_aging is taken as at
the date asked for, in both directions: an invoice issued after it is not on the books, a
payment made after it has not happened, and a credit note issued after it has not been
given.
The second thing measurement showed: paid_minor and payments[] on an invoice do not
have to agree, and routinely do not. invoice_mark_paid writes both, but deposit_apply
raises paid_minor and appends no payment row at all, and an invoice created before that
field existed has no rows either. Reconstructing receipts from payments[] would have
lost 300.00 of the worked month's 900.00 of receipts, a third of the cash, with no error
anywhere. paid_minor is treated as the authority and the rows are only the attribution.
Rules this server holds to
A deposit is money that moves once. Applying a deposit already writes the payment on the invoice, so the statement counts it there and breaks it out as "of which deposits applied" rather than crediting it a second time. Deposit money still held is a memo line and is never part of the balance: it is the client's money until it is applied.
Currencies are never added together. One statement is one currency, and a client billed in two is asked which. There is no exchange rate in this server, so a single figure across a EUR ledger and a USD one would be one it made up.
Due today is not overdue. An invoice enters the 0-30 bucket on the first day past its due date. What is outstanding but not yet due is reported beside the buckets, never inside them and never hidden.
A credit note reduces the invoice it names and no other. An open balance floors at zero and any excess is reported as unapplied credit, rather than quietly cancelling an invoice the client never agreed it against.
No chaser invents a charge. The three dunning levels differ in tone and deadline and in nothing else. No level states a late fee, an interest rate or a legal cost, because this server holds no contract terms, no statutory rate and no jurisdiction, and the one place never to put a made-up number is a demand for money.
A chaser for a client with nothing overdue is refused, and the refusal says what is outstanding but not yet due.
Privacy
All data stays on your machine. The invoices, credit notes and deposits are read from
${XDG_DATA_HOME:-~/.local/share}/mcp-servers/, this server's own register of built
statements is written to .../mcp-servers/statement-of-account/, and nothing is sent
anywhere. There is no network call in this server at all. License keys verify offline.
License
MIT. Support: support@zovo.one
Built by theluckystrike.
Use these docs as an MCP server
Any MCP client (Claude, Cursor, Windsurf, VS Code) can read this repository's documentation directly via GitMCP — no install:
Available Tools
8 toolsdunning_textWrite a dunning letterA
Write a payment chaser at level 1 friendly, 2 firm or 3 final demand: every OVERDUE invoice with its age, the total and your bank details. Refused if nothing is overdue. No interest is stated. Level 3 is Pro.
Inputs: level (required), client (required), as_of, currency, +2 more.
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.
Inputs: key (required).
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.
Inputs: no named parameters.
statement_agingAge the open invoicesA
Age open invoices into 0-30, 31-60, 61-90 and over 90 days past DUE date at a date, per client and currency, with the invoices themselves. Free. statements_report rolls up the whole book instead.
Inputs: as_of, limit, client, currency.
statement_buildBuild a statement of accountA
Build one client's statement for a period: opening, invoices, payments with deposits applied broken out, credit notes and closing, formatted and in minor units. Free: 5 a month; a rebuild is free.
Inputs: to (required), from (required), client (required), currency.
statement_pdfRender the statement of account as a PDFA
Call this tool to write one client's A4 statement of account and return the path. Titled STATEMENT OF ACCOUNT, movements in date order, BALANCE OUTSTANDING at the foot, and no VAT re-added. Pro.
Inputs: to (required), from (required), client (required), as_of, +2 more.
statements_reportWhat every client owesA
Receivables across every client at a date: totals and aging per currency, clients ranked by how much is OVERDUE, and the oldest overdue invoice. Pro. statement_aging is the free per-client view.
Inputs: as_of, limit.
statement_textPlain-text statement of accountA
Turn one client's statement into a plain-text letter for an email: movements in date order, opening and closing balances, deposit held, a sign-off. It counts toward the 5 a month; statement_pdf writes the A4 page.
Inputs: to (required), from (required), client (required), as_of, +3 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool has a clearly distinct purpose: license activation/status, dunning text, per-client aging, whole-book reporting, and statement building/PDF/text outputs. The descriptions explicitly cross-reference differences, such as statement_aging vs statements_report and statement_text vs statement_pdf, so there is no real ambiguity.
Names are consistently snake_case and mostly use the statement_ prefix, but the verb/noun pattern is mixed: license_activate and statement_build are noun+verb, while license_status, statement_pdf, statement_text, and statements_report are noun+noun. The conventions are readable but not uniform enough for a higher score.
Eight tools is well-scoped for this server: two license utilities, one dunning helper, two aging/report tools, and three statement output tools. Each tool earns its place and covers a distinct part of the statement workflow without redundancy.
The core statement workflow is well covered: build, text, PDF, aging, receivables report, dunning, and license state. Minor gaps exist, such as no license deactivation or quota/usage check for the free monthly statement builds, but these are workable and not likely to break common agent flows.
Maintenance
Related MCP Connectors
Client statements of account, ageing of open invoices and payment chasers as text or PDF.
Track client security and retainer deposits: hold, apply to an invoice, refund, statements.
Chase unpaid invoices: reminder, firm reminder and final notice letters, and a daily chase list.
Find overdue invoices, draft invoices, and chase payment. Sends need your confirmation.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables 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-
- AlicenseNot gradedqualityCmaintenanceLets 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
- AlicenseAqualityBmaintenanceEnables users to track unpaid invoices and generate an escalating ladder of payment-reminder letters — first reminder, second reminder, and final notice — anchored to the due date, plus overdue listings, aging buckets, and a daily chase list of what to send today. It records payments and letters sent, rendering each letter as Markdown or printable HTML without ever emailing anything itself.1146 npmMIT
- AlicenseAqualityCmaintenanceEnables accountants and bookkeepers to ask practice-wide questions across every connected client Xero organisation in one read-only view — overdue invoices, payroll shortfalls, client health scores, trending-trouble lists and practice totals such as revenue and average DSO. It also generates ready-to-send Excel month-end packs per client, with every reported figure accompanied by the rule or formula that produced it and no financial data persisted to disk.12MIT