kitsas-mcp
kitsas-mcp
An MCP server for local Kitsas bookkeeping files. Kitsas
is a Finnish double-entry bookkeeping application that stores each book as a
single SQLite .kitsas file on disk. As far as is known, this is the first
MCP server built for Kitsas: it lets an MCP client such as Claude read a
book's accounts, fiscal years, partners and vouchers, and create purchase
invoice drafts directly from a chat, for example from a PDF invoice dropped
into the conversation.
Kitsas must have the book closed
Kitsas holds an open book's file with PRAGMA LOCKING_MODE = EXCLUSIVE.
While Kitsas has the book open, no other process, including this server, can
read or write it: every attempt fails with a locked-database error. Close the
book in Kitsas before pointing this server at it. This is not a limitation of
this server; it is how Kitsas itself protects the file.
Drafts only, never the ledger
This server never books anything into the ledger. add_purchase_invoice
writes a new voucher in an unnumbered draft state, exactly like a document
Kitsas received but nobody has looked at yet. It gets no voucher number and
is invisible to a normal ledger listing. A human still has to open Kitsas,
review the draft, and approve it before it becomes part of the book's
bookkeeping. delete_draft is the only other tool that writes, and it can
only discard a voucher that has not reached the ledger. Every other tool
only reads.
Install
From a clone:
git clone <this repository>
cd kitsas-mcp
uv tool install .Or, once published:
uv tool install kitsas-mcpEither way you end up with a kitsas-mcp command on your PATH, which an MCP
client launches with --book /path/to/book.kitsas or the KITSAS_BOOK
environment variable pointing at the closed .kitsas file.
Claude Desktop
Add this to your Claude Desktop MCP server configuration:
{
"mcpServers": {
"kitsas": {
"command": "uv",
"args": ["run", "--directory", "/path/to/kitsas-mcp", "kitsas-mcp"],
"env": { "KITSAS_BOOK": "/path/to/kirjanpito.kitsas" }
}
}
}Claude Code
claude mcp add kitsas -e KITSAS_BOOK=/path/to/kirjanpito.kitsas -- uv run --directory /path/to/kitsas-mcp kitsas-mcpTools
list_accounts- list the book's chart of accounts, optionally filtered by a substring of the name or the first digits of the number.list_fiscal_years- list fiscal years, showing which is current and which are confirmed and closed to writes.find_supplier- find a partner by name, business id or IBAN.list_vouchers- list vouchers in a date range, ledger vouchers by default.get_voucher- get one voucher with all its entries and attachment names.suggest_account- which expense accounts a supplier's earlier bills were booked to, most used first; call this beforeadd_purchase_invoice.add_purchase_invoice- create a purchase invoice as an unapproved draft; never enters the ledger on its own.delete_draft- delete a voucher that is not yet in the ledger, including a draft Kitsas itself created; refuses anything already in the ledger.bank_balance- the book's balance on the bank account as of a date, for checking against a statement.bank_movements- every ledger entry on the bank account in a date range, with a running balance.
Safety
These are the invariants the code enforces, not just intentions:
No write this server makes ever lands at or above the ledger threshold.
add_purchase_invoicewrites in the draft state (TILA_SAAPUNUT) that Kitsas itself uses for an unapproved incoming document, anddelete_draftwrites the deleted state (TILA_POISTETTU) Kitsas uses for a discarded one. Nothing this server writes can be mistaken for a booked entry.A draft never gets a voucher number (
tunniste); Kitsas allocates that only when a human approves it.add_purchase_invoiceverifies this by reading the row back before committing.Nothing can be written into a confirmed fiscal year.
add_purchase_invoicelooks up the fiscal year for the booking date and refuses if it has been confirmed, naming the confirmation date.A backup of the book is taken before every write transaction, alongside its
-wal/-shmsidecars if present. A write is refused, and the book left untouched, if the backup cannot be made.Anything already in the ledger is read-only through this server.
delete_draftrefuses a voucher whose state has reached the ledger threshold, both before and again inside the write transaction, and no update statement it issues can touch such a voucher even on its own.An IBAN already bound to one partner is never silently re-pointed to another.
add_purchase_invoicerefuses instead of overwriting the binding, naming who the IBAN currently belongs to.An attachment over 20 MB is refused before it is even read from disk, so an oversized file is never copied into the book or into every future backup of it.
A business id read off an invoice is written onto an existing partner only when that partner has no business id yet and no vouchers in the ledger. One already on file is left alone, and so is a blank one on a partner that already has bookkeeping history: the draft is still written, and the summary names the partner that was left as it was, so the correction can be made in Kitsas. A wrong value read from a scan would otherwise be undoable except by restoring a backup.
Backups accumulate
Every write takes its own timestamped .bak copy of the whole book, plus its
-wal/-shm sidecars, in the same folder as the book. Nothing prunes them.
Each copy contains every PDF embedded in the book, so a book with many
attachments grows a folder of large duplicates over a year of use. Tidy the
old .kitsas.*.bak files yourself now and then, keeping the recent ones.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Valtterios/kitsas-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server