theluckystrike

mcp-statement-of-account

Community theluckystrike
Updated

Practical MCP servers: time tracker, price tracker, spreadsheet, invoice. Local, offline-licensed, one-time Pro.

mcp-statement-of-account

Send a client the one document that answers "what do I actually owe you". This MCP serverreads the books you already keep in this suite -- your invoices, your credit notes and yourdeposits -- and turns them into a statement of account for a period: the balance you werecarrying at the start, every invoice you issued, every payment that came in, every creditnote 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 anythingback into your invoices, and it never invents a late fee.

Built by theluckystrike.

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-account

Cursor

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

Tools

tool what it does
statement_build 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
statement_aging 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
statement_text The same statement as plain text, movements in date order, ready to paste into an email
statement_pdf The same statement as an A4 PDF titled STATEMENT OF ACCOUNT, on the same page layout as your invoices and credit notes
dunning_text A payment chaser at level 1 (friendly), 2 (firm) or 3 (final demand), with the overdue list and your bank details
statements_report Every client at once: what is outstanding per currency, aged, and the oldest overdue invoice in the book
license_status Free or Pro, and where to upgrade
license_activate Activate a Pro key

Plus the statement://sources resource, which says which of the three stores this servercould 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
statement_aging unlimited unlimited
statement_text yes yes
dunning_text levels 1 and 2 yes yes
dunning_text level 3, final demand no yes
statement_pdf no yes
statements_report no yes
PDF footer credit shown removed

Aging is free and unlimited on purpose. "Who owes me money" is the question this wholeserver exists for, and a free tier that hides it is a demo rather than a tool. The meter ison the statement, the document that actually goes to a client, and it counts distinctstatements: the same client, period and currency built again is free forever.

Get Pro -- one-time, lifetime, for thisserver. 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
invoices.json mcp-invoice the invoices, their due dates and how much of each is paid
credit-notes.json mcp-billing-docs the credit notes, already stored with a negative sign
deposits.json mcp-deposits 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 reportedas such on every figure, because a balance that could not be computed must never be shownas a balance of nothing owed. The one store the server refuses to work without is theinvoice ledger.

A measured insight

Aging a past date with today's payment figures is not slightly wrong, it is silentlyempty. Aging is usually written as "take each invoice, subtract what has been paid, andbucket by the due date". The subtraction is the part nobody dates. On the worked month intest/_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 paid_minor 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 apayment that arrived two days later has already been subtracted from it. The failure isinvisible: the answer looks tidy, the buckets add up, and it cannot be reproduced nextmonth because the input keeps moving. So every figure in statement_aging is taken as atthe date asked for, in both directions: an invoice issued after it is not on the books, apayment made after it has not happened, and a credit note issued after it has not beengiven.

The second thing measurement showed: paid_minor and payments[] on an invoice do nothave to agree, and routinely do not. invoice_mark_paid writes both, but deposit_applyraises paid_minor and appends no payment row at all, and an invoice created before thatfield existed has no rows either. Reconstructing receipts from payments[] would havelost 300.00 of the worked month's 900.00 of receipts, a third of the cash, with no erroranywhere. 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 onthe invoice, so the statement counts it there and breaks it out as "of which depositsapplied" rather than crediting it a second time. Deposit money still held is a memo lineand 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 clientbilled in two is asked which. There is no exchange rate in this server, so a singlefigure 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 itsdue date. What is outstanding but not yet due is reported beside the buckets, neverinside them and never hidden.
  • A credit note reduces the invoice it names and no other. An open balance floors atzero and any excess is reported as unapplied credit, rather than quietly cancelling aninvoice the client never agreed it against.
  • No chaser invents a charge. The three dunning levels differ in tone and deadline andin nothing else. No level states a late fee, an interest rate or a legal cost, becausethis server holds no contract terms, no statutory rate and no jurisdiction, and the oneplace 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 isoutstanding 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 builtstatements is written to .../mcp-servers/statement-of-account/, and nothing is sentanywhere. There is no network call in this server at all. License keys verify offline.

License

MIT. Support: [email protected]

Built by theluckystrike.

MCP Server ยท Populars

MCP Server ยท New

    esperanza-volkov

    confdiff

    Semantic, format-aware diff for config & structured-data files (JSON, YAML, TOML, INI, .env, .properties, CSV, XML). See what actually changed โ€” keys and values, not text noise.

    Community esperanza-volkov
    butterbase-ai

    @butterbase/mcp

    Open-source backend-as-a-service. Postgres, auth, storage, functions, AI gateway, MCP.

    Community butterbase-ai
    adamsiwiec1

    Host MCP SSE Server on Google Cloud Run

    Host an Model Context Protocol SSE deployment on Cloud Run, Authenticating with IAM.

    Community adamsiwiec1
    Mitek99

    DeepView MCP

    DeepView MCP is a Model Context Protocol server that enables IDEs like Cursor and Windsurf to analyze large codebases using Gemini 2.5 Pro's extensive context window.

    Community Mitek99
    prisma

    orm

    Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB

    Community prisma