Connect an AI assistant (MCP)
MoneyLights has a built-in MCP server, so an AI assistant — Claude Desktop, Claude Code, an IDE agent, anything that speaks the protocol — can work with your organization’s data on request.
It is the same credential as the REST API: an MCP connection is an API key, with the same scopes, the same limits and the same revoke button. There is nothing separate to manage.
Connecting
Section titled “Connecting”The endpoint is https://api.moneylights.app/mcp (Streamable HTTP). A typical
client configuration:
{ "mcpServers": { "moneylights": { "url": "https://api.moneylights.app/mcp", "headers": { "X-API-Key": "ml_sk_..." } } }}With Claude Code it is one command:
claude mcp add --transport http moneylights https://api.moneylights.app/mcp \ --header "X-API-Key: ml_sk_..."Create the key in Settings → API keys and grant it only the scopes the assistant needs. Everything requires the key, including listing the tools.
What the assistant can do
Section titled “What the assistant can do”The tool list is computed from your key’s scopes, on every request. A key without a scope is never even told the corresponding tool exists.
| Tool | Scope | What it does |
|---|---|---|
get_cashflow_overview | cashflow:read | Monthly income/expense/net, opening balance, top categories |
get_analytics_overview | analytics:read | Aggregates by category, client, project and person |
list_transactions | transactions:read | Transactions, filtered and paged, each with the documents linked to it |
list_documents | documents:read | Documents and their extracted fields, each with the movements linked to it |
get_document_file | documents:read | The original file of one document — the PDF or image the app shows |
get_pending_distribution | profitpulse:read | Pending Safe-to-Spend distributions |
list_vendors | vendors:read | Vendors, with total spend |
list_clients | clients:read | Clients, with total revenue |
list_projects | projects:read | Projects, with totals and targets |
upload_document | documents:write | Files an invoice or receipt into your documents |
Both overviews compute on the same base and say so: every response carries a basis — period,
currencies, the accounts covered (every visible one, unless asked for by id), and how transfers between the
organization’s own accounts were treated. By default they are excluded from income and expenses,
leg by leg, exactly as the app’s Cashflow view shows them; pass includeInternalTransfers: true to
either tool for the raw bank movement, which the basis then labels as such and which is not
comparable with the default. Compare figures across the two tools only when their basis matches.
netCashResult is income minus expenses of bank movements — a cash result, not accounting profit.
Which document goes with which movement
Section titled “Which document goes with which movement”Both lists say it, from both sides, the way the app shows it. Every transaction carries
linkedDocuments and every document carries linkedTransactions; each entry names the other
side and a link:
confirmed— the document is matched to the movement, which counts as documented.suggested— the matcher proposes the pairing; nobody has confirmed it and the movement is still missing its document. The entry carries the matcher’sscore.
An assistant can therefore tell no invoice from an invoice waiting to be confirmed from already filed — and cannot change any of it, because this connection has no tool for that.
A movement may carry several confirmed documents. A document links to at most one movement, so
an invoice paid in several parts shows only the movement it was matched to. A document still
Processing has no links yet; None means none.
Scopes still hold: the far side of a link is described (supplier and number, or description and amount) only to a key that can read that resource too. With one scope you get the other side’s id, the kind of link and the score — enough to know a movement is documented, not what the invoice says.
Reading an original
Section titled “Reading an original”get_document_file takes a documentId from list_documents and returns the stored file
itself — the same PDF or image the app opens — as an embedded resource with its MIME type
(application/pdf, image/jpeg, …), next to the document’s id, file name and size — files up
to 10MB, the same ceiling as an upload. That is
how an assistant checks whether a difference comes from the invoice, from what was extracted or
from the movement it was matched to, without exporting anything. It is a read: nothing on the
document, its extracted fields or its links changes. A document that is not yours is simply
not found.
Filing documents
Section titled “Filing documents”upload_document is the one tool that writes, and it was chosen for that
role deliberately: it only ever adds. The assistant sends the file
(PDF or image, up to 10MB) and MoneyLights runs it through the same pipeline
as an upload in the app — stored, its fields extracted (supplier, date,
number, amounts) and auto-matched against your bank transactions.
Sending the same file twice never duplicates your data: the re-upload is recorded as a flagged duplicate pointing at the original. Everything the assistant files is visible — and deletable — in the app.
Every other write (creating clients, reclassifying transactions, configuring envelopes…) stays in the app on purpose: those actions assume a human confirming them.
Curated prompts
Section titled “Curated prompts”The server also offers ready-made starting points — a monthly cashflow review, a vendor spend analysis, a missing-documents cleanup — listed only when your key can run every tool they need. Use them as-is or edit freely.
Security
Section titled “Security”- The assistant is bounded by the key, re-checked on every request. Demote or remove the key’s creator and the assistant narrows or stops on the next call.
- Financial data contains text written by strangers — payment references, emailed documents. Tool results are delivered inside a marked boundary telling the model to treat them as data, never as instructions. Treat that as a mitigation, not a guarantee, and scope keys tightly.
- To disconnect an assistant, revoke its key in Settings → API keys. Immediate, always available.
Give each assistant its own key — one per client means you can cut one without disturbing the rest.