Skip to main content
Glama
Valtterios

kitsas-mcp

by Valtterios

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.

Related MCP server: merit-aktiva-mcp

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.

A book on a network share

A book kept on a NAS or a Windows share works, addressed either by its UNC path (\\server\share\kirjanpito.kitsas) or through a mapped drive letter. The same rule applies as for a local book: Kitsas itself must have it closed, and so must every other Kitsas on the network, because the exclusive lock is on the file.

Install

From a clone:

git clone <this repository>
cd kitsas-mcp
uv tool install .

Or, once published:

uv tool install kitsas-mcp

Either 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-mcp

Tools

  • 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. confirmed is the confirmation date or null; confirmed_unknown is true for a year whose stored data cannot be read, which is closed to writes too.

  • find_supplier - find a partner by name, business id or IBAN; returns each partner's id, name, business id and IBANs. Names also match with their accents ignored, so searching Karkkainen shows the book's Kärkkäinen.

  • 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 before add_purchase_invoice.

  • add_purchase_invoice - create a purchase invoice as an unapproved draft; never enters the ledger on its own. partner_id names the partner outright when the supplier name would find the wrong one, and confirm_new_partner says that a name resembling an existing partner really is a different supplier.

  • 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_invoice writes in the draft state (TILA_SAAPUNUT) that Kitsas itself uses for an unapproved incoming document, and delete_draft writes 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_invoice verifies this by reading the row back before committing.

  • Nothing can be written into a confirmed fiscal year. add_purchase_invoice looks up the fiscal year for the booking date and refuses if it has been confirmed, naming the confirmation date.

  • No write ever proceeds without a backup of the book in place, alongside its -wal/-shm sidecars if present. A write is refused, and the book left untouched, if the backup cannot be made. One backup is taken per book per server session, not per write: the first write copies the book and every later write in that session is protected by that same copy. See "Backups" below for what that costs and what it does not.

  • A refused write costs no backup. Everything that can be judged without writing is judged on a read connection first: the fiscal year, the accounts, the amounts, the attachment, an explicit partner_id, an ambiguous or resembling supplier name, an IBAN that belongs to another partner. The same checks run again inside the write transaction, so nothing rests on the earlier answer still being true. A write that does open a transaction and then rolls back removes the backup it took, but only when that backup protects no write that has already succeeded.

  • Anything already in the ledger is read-only through this server. delete_draft refuses 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.

  • A supplier name is resolved to a partner the same way everywhere: find_supplier, suggest_account and add_purchase_invoice share one rule, so the account history you are shown belongs to the partner the voucher is then attached to. A name that identifies a partner already in the book joins that partner instead of forking a duplicate beside it, and a match on a name that is not the partner's own is named in the summary. A name matching several partners is refused, listing them: which supplier a bill belongs to is the bookkeeper's call. Only a name that matches no partner creates one, and not even then when an existing partner differs from it only in accents (the next point). Names are compared case-folded with Python's str.casefold, not with SQLite's lower() and LIKE, which fold ASCII only: in a Finnish book Kärkkäinen Oy and KÄRKKÄINEN OY have to be one partner, and under lower() they were two.

  • A supplier name that matches no partner, but that a partner already in the book matches once accents are ignored, is refused rather than quietly creating a second partner. Karkkainen billed against a book holding Kärkkäinen Lahti matched nothing, because case folding leaves ä alone, and the book grew a duplicate supplier with no warning; dropped umlauts are ordinary in Finnish practice, from an OCR pass, a supplier's ASCII-only billing system or a treasurer typing quickly. The refusal names the existing partner and its id. It is a refusal and not a remark because in Finnish ä and a are different letters, so the two spellings genuinely can be two different suppliers, and choosing between real alternatives in someone's books is not this server's call. Both ways out are in the message: partner_id books onto the partner that is already there, and confirm_new_partner creates the new one beside it. find_supplier matches accent-blind too, so the resemblance can be seen before a bill is entered rather than after it is refused.

  • Only the voucher is written when the supplier name matched a partner by a substring of its name rather than by the name itself. That partner keeps its own business id and its own IBAN, and the summary says both were skipped. The voucher is a draft delete_draft can reverse; an edit to a partner that already existed is not, and a substring match is a guess: a sole trader "Nieminen" matches the member "Kari Nieminen", and it would be that member's record taking the supplier's bank account.

  • partner_id is the way out when the name rule cannot reach the right partner, which is exactly the case above: a supplier whose real name is contained in another partner's name matches that partner however fully it is spelled. Given partner_id, add_purchase_invoice uses that partner with no name matching at all and refuses if no such partner exists; supplier_name is then only the text written on the voucher, and the summary says which partner the voucher went to when the two differ. find_supplier gives the ids.

  • An IBAN already bound to one partner is never silently re-pointed to another. add_purchase_invoice refuses 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, no vouchers in the ledger, and was identified exactly, by its own name or by partner_id. 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.

  • Every failure an MCP client sees is a message naming the cause and the fix, flagged as an error on the response rather than only inside the JSON payload. That includes failures the code did not anticipate: an unexpected exception inside a tool is reported as an internal error, not raised into the transport where it would be delivered without the error flag set.

Backups

The first write to a book in a server session copies the whole book, plus its -wal/-shm sidecars, to a timestamped .kitsas.<stamp>.bak beside it. Every later write in that session reuses that copy and copies nothing, and a call that is refused before it writes copies nothing either. Restarting the client, which restarts this server, starts a new session and so takes a new copy at its first write.

That is much cheaper than a copy per bill: ten bills against a 110 MB book cost 110 MB rather than 1.1 GB, and refused calls cost nothing at all. The trade-off is real and worth knowing: the copy is the book as it stood before the session's first write, so if a bad booking is noticed after several later ones, restoring that copy undoes them all. It is the last resort rather than the first. A draft this server wrote is reversible with delete_draft, and Kitsas itself is the undo for anything already approved; the .bak is for the case where neither of those will do.

Nothing prunes the .bak files. Each one contains every PDF embedded in the book, so they are large. Tidy the old .kitsas.*.bak files yourself now and then, keeping the recent ones.

Available Tools

10 tools
add_purchase_invoiceA

Create a purchase invoice as a DRAFT. It does not enter the ledger and gets no voucher number until a human reviews and approves it in Kitsas; this tool can never book money on its own. Expense lines are debited; the total is credited to the bank account unless credit_account says otherwise. Call suggest_account first so the supplier keeps landing on the same account it always has.

ParametersJSON Schema
NameRequiredDescriptionDefault
ibanNo
linesYesExpense lines: account (int), amount (euros as a string), description (optional)
due_dateNoYYYY-MM-DD
pdf_pathNoThe original invoice, attached to the voucher
referenceNo
business_idNo
descriptionNo
booking_dateYesYYYY-MM-DD, must be in an open fiscal year
invoice_dateNoYYYY-MM-DD
supplier_nameYes
credit_accountNoDefaults to the bank account

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations were provided, but the description thoroughly discloses behavior: it never books money, remains a draft, lacks a voucher number until approval, and details debit/credit entry logic, including the credit_account override.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, three sentences, with no fluff. It front-loads the key draft behavior and then explains accounting details and a prerequisite, all relevant and efficiently stated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Though there is no output schema, the description explains the tool's side effects and accounting flow well. Minor gaps remain regarding expected return values or error conditions, but these are not critical given the overall clarity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaning for credit_account and booking_date (open fiscal year), but many parameters (iban, reference, business_id, description, invoice_date, supplier_name) are only defined by schema names or minimal schema descriptions. Schema coverage is only 55%, leaving gaps that the description does not fill.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the action 'Create a purchase invoice as a DRAFT' with a specific resource. The draft status and lack of ledger impact differentiate it from other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance to call suggest_account first for consistent supplier accounts, and explains the draft workflow and accounting treatment, helping the agent choose when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bank_balanceB

The book's balance on the bank account as of a date, for checking against a bank statement.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNo
on_dateYesYYYY-MM-DD

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must convey behavioral aspects. It implies a read operation (checking a balance) but does not disclose side effects, error behavior, or permissions. It offers minimal transparency beyond the basic function.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, succinct sentence that directly conveys the tool's purpose and typical use. There is no unnecessary verbosity or convoluted structure, making it easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description offers a clear use case but omits essential context such as what the account parameter represents or how the balance is formatted. This leaves some ambiguity for an agent deciding on the call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description clarifies the 'on_date' parameter as 'as of a date', but provides no meaning for the 'account' parameter, which remains undescribed in the schema as well. Since the account is critical to the operation, the lack of semantic explanation is a notable gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description indicates that the tool returns a balance for a specific date, with a clear use case of checking against a bank statement. However, it lacks an explicit verb and the term 'book's balance' is ambiguous, possibly meaning the account balance in the books.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear context for when to use this tool ('for checking against a bank statement'), but it does not mention any alternatives or explicitly state when not to use it. This gives a reasonable but incomplete usage guideline.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bank_movementsA

Every ledger entry on the bank account in a date range, with a running balance, for reconciling against a statement.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNo
date_toYesYYYY-MM-DD
date_fromYesYYYY-MM-DD

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description implies a read-only operation and describes the returned data (ledger entries, running balance), but it does not clarify behavior when the optional account parameter is omitted, nor does it mention ordering, date inclusivity, or error conditions. With no annotations present, more transparency would be beneficial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that conveys the core purpose and output without unnecessary detail. It is well-structured and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main purpose and output shape (entries with running balance), but it omits useful context such as whether all accounts are included when account is absent, sort order, or the exact fields returned. Since there is no output schema, a bit more detail would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description mentions a date range and a bank account, which partially maps to the parameters, but the account parameter has no schema description and its optionality is not explained. The date parameter descriptions only give format, not semantics like inclusivity or timezone handling.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns every ledger entry for a bank account within a date range, including a running balance. It is easily distinguishable from siblings like bank_balance or list_accounts because it emphasizes detailed transaction-level data for reconciliation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly mentions the intended use case: reconciling against a statement. It does not explicitly compare with alternatives or state when not to use it, but the purpose is clear enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_draftA

Delete a voucher that is not yet in the ledger. That includes drafts Kitsas itself created, such as a document waiting in its inbox or a draft someone is still working on, not only drafts this server wrote. Refuses any voucher that has already reached the ledger.

ParametersJSON Schema
NameRequiredDescriptionDefault
voucher_idYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavior. It states the key refusal condition and the inclusive scope, but does not mention irreversibility, permission requirements, or any side effects beyond deletion. It does not contradict annotations (none).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the main action, then scope clarification. Every word earns its place; no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter delete tool with no output schema, the description covers the essential usage conditions and exclusions. It could mention error behavior or irreversibility, but these are minor given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one required integer parameter with zero description coverage. The description does not explicitly define voucher_id beyond the tool's context, leaving the agent to infer that it is the identifier of the draft to delete. This is a gap given the lack of schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (delete) and resource (voucher not yet in ledger), and clarifies the scope by including drafts Kitsas itself created. It clearly distinguishes from sibling tools like list_vouchers and add_purchase_invoice by its destructive nature and target state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear conditions for when to use: when a voucher is not yet in the ledger, including drafts. It states what it refuses (ledger vouchers), implying not to use for posted vouchers. However, it does not explicitly name alternatives or provide a 'when not to use' beyond the refusal condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_supplierA

Find a partner by name, business id or IBAN.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does not disclose whether the operation is read-only, how results are returned (single vs. list), or any side effects. The name implies a read operation but this is not explicitly stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that directly conveys the tool's function. It is well-structured and free of unnecessary words, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search tool, the description provides sufficient context to understand its purpose and input requirements. It does not explain output format or edge cases, but given the lack of an output schema and the tool's simplicity, these omissions are acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has a single 'query' string parameter with no description. The tool description indicates it can be a name, business id, or IBAN, providing some meaning, but it does not clarify matching behavior (exact vs. partial), format expectations, or handling of ambiguous inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Find') and resource ('partner'), and specifies the search criteria (name, business id, or IBAN). It is distinguishable from sibling tools, none of which are find operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool over alternatives, but the sibling context (e.g., banking, vouchers) suggests it is for supplier lookup. No explicit conditions or alternatives are mentioned, leaving some ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_voucherB

Get one voucher with all its entries and attachment names.

ParametersJSON Schema
NameRequiredDescriptionDefault
voucher_idYes

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says 'Get' which implies a read operation, but it does not explicitly state that it is read-only, mention error handling (e.g., what happens if the voucher is not found), or describe any side effects. The disclosure is minimal and leaves important behavior to inference.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly written sentence that front-loads the core purpose and the key output details. There is zero wasted verbiage, and the sentence is immediately clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (one parameter, no output schema, no annotations), the description is adequate but not complete. It specifies that entries and attachment names are included, which is useful, but it omits information about error cases, pagination (if any), or whether the operation is read-only. For a simple get, the description is sufficient for basic use but lacks robustness for an agent to anticipate edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one parameter, voucher_id (integer), which is self-explanatory by name. However, the description does not mention this parameter at all, and schema description coverage is 0%. The description adds no semantic meaning beyond the schema; the agent must rely on the parameter name and type, which is adequate but not enhanced. With a single obvious parameter, the lack of description is a minor gap, but it does not fully compensate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Get), a specific resource (one voucher), and adds detail about what is returned (all its entries and attachment names). This clearly distinguishes it from list_vouchers, which presumably returns multiple vouchers. The use of 'one' explicitly signals a single-object retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for retrieving a single voucher, which differentiates it from list_vouchers, but it does not explicitly state when to use this tool versus alternatives or mention any exclusions. There is no direct guidance on when to prefer get_voucher over list_vouchers or other siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_accountsA

List the book's chart of accounts. Optional search matches a substring of the account name, or the start of the account number.

ParametersJSON Schema
NameRequiredDescriptionDefault
searchNoSubstring of the name, or the first digits of the number

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the burden. 'List' implies a read-only operation, and the search behavior is described. However, it doesn't explicitly state that no data is modified or mention any side effects, authentication, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, no unnecessary words, and gets straight to the point. It is well-structured and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one optional parameter and no output schema, the description is sufficiently complete. It states the action and the filtering behavior, which is all an agent needs to decide to use it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers the only parameter 'search' with a clear description, and the tool description reinforces it by explaining that it matches a substring of the name or the start of the number. This adds clarity about optionality and matching rules.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists the book's chart of accounts, with a specific verb and resource. It is distinct from the sibling tools, which handle drafts, bank balances, fiscal years, suppliers, vouchers, and invoices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool—whenever a list of accounts is needed—and the optional search parameter indicates how to narrow results. It doesn't explicitly reference alternatives, but the purpose is self-explanatory.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_fiscal_yearsA

List fiscal years, showing which is current and which have been confirmed. Nothing can be written into a confirmed year.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that confirmed years are immutable ('Nothing can be written into a confirmed year'), which is a behavioral constraint beyond just listing. It does not explicitly state side effects (though listing implies read-only), but the warning adds useful transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that conveys the purpose and an important behavioral note without unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully explains what the tool does (lists fiscal years, identifies current and confirmed) and includes a relevant warning about confirmed years, providing enough context for a user to know when and why to call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters, so coverage is complete. The description adds nothing about parameters, but since there are none, this is neutral and meets the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List') and the resource ('fiscal years'), and specifies the output includes current and confirmed status. This distinguishes it from sibling tools like delete_draft or add_purchase_invoice.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly mention when to use this tool versus alternatives. The note that nothing can be written into a confirmed year provides indirect guidance (e.g., check before writing), but it lacks clear when-to-use or when-not-to-use instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_vouchersA

List vouchers in a date range. Shows ledger vouchers unless a state is given.

ParametersJSON Schema
NameRequiredDescriptionDefault
stateNo20 for drafts this server created
accountNo
date_toYesYYYY-MM-DD
supplierNoPartner id
date_fromYesYYYY-MM-DD

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of disclosing behavioral traits. It does not explicitly state that the tool is read-only or has no side effects, although the verb 'list' may imply it. Since no safety or permission information is mentioned, transparency is limited.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no redundant words. It front-loads the primary action and then adds a critical conditional behavior, making it easy to parse and remember.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list operation, the description fully covers what an agent needs to know: what is listed, the required date range, and the optional state filter with its default behavior. No missing context that would prevent correct usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Four of five parameters have meaningful descriptions: date_from and date_to include format hints, state gives the integer code meaning, and supplier clarifies it is a partner id. The account parameter lacks any description, preventing full coverage of the parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the action (list vouchers), the scope (date range), and the default behavior (ledger vouchers unless a state is given). The verb and object are specific enough to immediately distinguish this from other list-type tools in the sibling set.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides no explicit guidance on when to use this tool versus the sibling tools (e.g., get_voucher, list_accounts). The note about state is a behavioral detail, not a comparative usage guideline, so the agent is left to infer when this is the right choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

suggest_accountA

Which expense accounts this supplier's earlier bills were booked to, most used first. Empty for a supplier with no history. Call this before add_purchase_invoice so a recurring supplier keeps landing on the same account instead of a guess.

ParametersJSON Schema
NameRequiredDescriptionDefault
supplierYesPartner name, or the partner id as a number or a digit string

TDQS

A4.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explains output behavior (most used first, empty for no history) but does not explicitly state whether the operation is read-only or if it has side effects. With no annotations provided, the description carries the full burden, and this omission is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, consisting of two short sentences with no redundant information. It efficiently conveys purpose, usage, and output behavior without unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and no output schema, the description provides all necessary context: what it does, when to use it, what it returns, and edge cases. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The parameter 'supplier' is described as 'partner name, or the partner id as a number or a digit string', adding meaningful detail beyond the schema's type definition. This clarifies exactly what values are acceptable and how to provide them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: suggesting expense accounts based on a supplier's historical bills, ordered by frequency. It distinguishes itself from siblings like list_accounts by being supplier-specific and from add_purchase_invoice by being a pre-step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to call this tool before add_purchase_invoice to ensure recurring suppliers land on the same account, avoiding guesses. This provides clear when-to-use guidance and implies an alternative (guessing) that this tool replaces.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 10 tool updatesv0.1.0
    • First observedadd_purchase_invoice
    • First observedbank_balance
    • First observedbank_movements
    • First observeddelete_draft
    • First observedfind_supplier
    • First observedget_voucher
    • First observedlist_accounts
    • First observedlist_fiscal_years
    • First observedlist_vouchers
    • First observedsuggest_account

TDQS

A3.9/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct resource or action: vouchers, bank data, accounts, fiscal years, suppliers, and draft deletion are clearly separated. Even related tools like bank_balance and bank_movements differ by aggregation level, and list_vouchers vs get_voucher are unambiguous.

Naming Consistency4/5

Most tools follow a verb_noun snake_case pattern such as list_accounts, find_supplier, and add_purchase_invoice. bank_balance and bank_movements are noun-only names, which is a minor inconsistency, but the naming remains predictable and readable overall.

Tool Count5/5

Ten tools is well-suited for an accounting-focused MCP server: enough to cover the main workflows without overwhelming an agent. The count feels balanced and purposeful.

Completeness4/5

The tool set covers the core read workflows plus adding purchase invoices, suggesting accounts, and deleting drafts. It lacks update/delete operations for most entities, but for the apparent assistant-oriented purpose it addresses the essential tasks without major gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    A read-only MCP server for SimpleShop accounting data, enabling AI agents to find documents, download PDFs, inspect products, and review sales exports.
    5
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables read-only access to Merit Aktiva accounting data, including customers, vendors, sales invoices, accounts, payments, and taxes, through natural language MCP tools.
    77
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables 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
    -
  • A
    license
    B
    quality
    C
    maintenance
    Enables querying and managing a live accounting ledger, including transactions, balances, VAT summaries, deadlines, and documents, from any MCP client.
    86
    91 npm
    MIT