Double-entry is not a validation nicety, it is what makes the ledger a ledger, and an agent composing a journal entry has no reason to know that unless told. Putting the constraint in the description means a malformed entry is caught by the caller rather than by the accountant. Cost centres and projects being exposed is the other sign this was built by someone who does the work — expense allocation is where bookkeeping actually gets tedious, and most integrations omit it entirely. Be clear that send_invoice emails a real customer and create_voucher posts to real books; this is not a reporting layer.
A Visma eAccounting client covering the accounting cycle in both directions: sales side with customers, quotes, orders, invoices and payments; purchase side with suppliers and their bills; plus journal entries and the ledger structure underneath.
- Customer invoices listed with OData filter syntax, opened in full, created with line items, sent by email, and their payments listed separately.
- The purchase side kept distinct: incoming supplier invoices listed and recorded, with supplier details available.
- create_voucher states its own constraint — rows must balance, total debit equal to total credit — so a malformed journal entry is refused rather than posted.
- The ledger structure is readable: the chart of accounts, fiscal years, and company settings.
- Projects and cost centres listed for expense allocation, which is where most accounting integrations stop short.
- Sales orders and quotes covered alongside invoices, so the pre-invoice stage exists too.
VISMA_ACCESS_TOKEN. This writes to real books — invoices are created and sent, and journal entries posted.
One command plus a key — npx -y visma-eaccounting-mcp-server, then supply credentials
