Buchhaltungsbutler MCP
This MCP server gives an AI assistant full control over a BuchhaltungsButler accounting cloud account through 46 MCP tools covering all 54 API endpoints.
Read-only queries: list and fetch accounts, cost locations, creditors, debtors, posting accounts, postings, receipts, transactions, assigned links, and financial reports (BWA, sums/balances, postingaccount ledgers).
Create records: add bank/cash accounts, cost locations, creditors, debtors, posting accounts, receipts (with or without file upload), transactions, invoices (final, draft, e-invoice), free postings, and receipt/transaction postings.
Update master data: rename/change cost locations, creditors, debtors, and posting accounts.
Link/unlink records: assign receipts to transactions, assign receipts to free postings, and unassign receipts from transactions.
Revert state: unconfirm receipt/transaction/free postings and restore deleted receipts.
Destructive actions: delete cost locations (permanent), delete receipts (restorable), and cancel postings (delete or reverse).
Safety features: tools are categorized as read-only, write, or destructive with MCP annotations; credentials stay server-side; rate limiting and authentication are enforced.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Buchhaltungsbutler MCP Show me my unpaid invoices from last month."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ohneben's Buchhaltungsbutler MCP
Lizenz & Checks
MCP-Register
Paketkennungen
Dieser Server hat eigene Kennungen. Was anders heißt, gehört nicht dazu:
Wo | Kennung |
MCP-Register |
|
Container (GHCR) |
|
npm |
|
Das npm-Paket buchhaltungsbutler-mcp ohne Scope ist ein anderes Projekt eines
anderen Autors (mrvnklm/buchhaltungsbutler-mcp)
und hat mit diesem hier nichts zu tun. Verzeichnisse, die von dieser Seite
dorthin verlinken, verlinken auf das falsche Paket.
Verwalte deine BuchhaltungsButler-Buchhaltung in natürlicher Sprache aus KI-Assistenten wie Claude, Cursor und jedem anderen MCP-Client.
Dieser Model-Context-Protocol-Server stellt die BuchhaltungsButler API v1 bereit — alle 54 Endpunkte als 46 MCP-Tools, aus der offiziellen OpenAPI-Spezifikation (Spec-Version 1.9.1) generiert. Jedes Tool ist sicherheitskategorisiert (nur lesend / schreibend / destruktiv), damit dein Assistent weiß, was eine Aktion tut, bevor er sie ausführt. Läuft über stdio (Claude Desktop und andere lokale Launcher) oder Streamable HTTP (gehostet in Docker).
Warum dieser Server
Manche MCP-Server leiten eine API einfach nur weiter. Dieser hier ist darauf ausgelegt, gefahrlos an ein Sprachmodell übergeben und im Alltag betrieben werden zu können:
Was du bekommst | Warum das zählt |
Alle 54 Endpunkte, automatisch generiert aus der offiziellen Spec | Vollständige Abdeckung von Belegen, Transaktionen, Buchungen, Rechnungen, Auswertungen und Stammdaten. Nichts handverlesen, nichts vergessen. |
Jedes Tool ist sicherheitskategorisiert 🟢 / 🟡 / 🔴 | Ein Banner am Anfang jeder Tool-Beschreibung sagt dem Modell genau, was passiert — lesen, anlegen, ändern, zurücknehmen oder löschen — bevor es handelt. |
Maschinenlesbare MCP-Annotationen ( | Hosts, die Annotationen auswerten (Claude gehört dazu), können Lesezugriffe automatisch zulassen und vor destruktiven Aktionen eine Bestätigung verlangen. |
Zwei Transporte: stdio und Streamable HTTP | Lokal in Claude Desktop nutzen — oder einen dauerhaft laufenden Server betreiben, den beliebig viele MCP-Clients über HTTP erreichen. |
Docker + docker-compose, Health-Check, Auto-Restart | Produktionsnahes Deployment ab Werk: |
Bearer-Token-Authentifizierung am HTTP-Endpunkt | Pflicht, sobald der Server über Loopback hinaus gebunden ist: ohne |
Eingebautes Rate-Limiting | Drosselt sich selbst unter dem BuchhaltungsButler-Limit von 100 Anfragen/Kunde/Minute, damit du nie dagegenläufst. |
Deine Zugangsdaten erreichen das Modell nie | Die Credentials liegen in der Server-Umgebung und werden pro Anfrage injiziert — der Assistent sieht nur Tool-Eingaben und API-Antworten. |
Im Vergleich
Nach aktuellem Stand ist dies der einzige dedizierte BuchhaltungsButler-MCP-Server. Alternativ könntest du einen generischen OpenAPI→MCP-Wrapper auf die Spec richten — das lässt allerdings einiges liegen:
Fähigkeit | Dieses Projekt | Generischer OpenAPI→MCP-Wrapper* |
Alle 54 BuchhaltungsButler-Endpunkte abgedeckt | ✅ | ✅ |
🟢 / 🟡 / 🔴 Sicherheitskategorie + Banner pro Tool | ✅ | ❌ |
| ✅ | ➖ |
| ✅ | ➖ |
Eingebautes Rate-Limiting (bleibt unter BBs 100/Kunde/Min.) | ✅ | ❌ |
| ✅ | ✅ |
Streamable-HTTP-Transport | ✅ | ➖ |
Docker + docker-compose, Health-Check, Auto-Restart | ✅ | ❌ |
Erzwungene Bearer-Token-Auth am Endpunkt | ✅ | ❌ |
Credentials serverseitig injiziert, nie ans Modell gesendet | ✅ | ➖ |
Lizenz | MIT | unterschiedlich |
*Generische OpenAPI→MCP-Wrapper machen aus jeder Swagger-/OpenAPI-Spec MCP-Tools. Sie erreichen dieselben Endpunkte, behandeln aber jede Operation gleich — keine Sicherheitskategorien, keine Betriebsgeschichte, keine auf echte Buchhaltungsdaten abgestimmten Leitplanken. „➖“ = je nach Werkzeug unterschiedlich / nicht garantiert.
Related MCP server: sevdesk-mcp
Was du damit machen kannst
Sobald der Server verbunden ist, kannst du deinen Assistenten zum Beispiel bitten:
„Liste alle Eingangsbelege vom letzten Monat auf, die noch offen sind.“
„Erstelle einen Rechnungsentwurf für die ACME GmbH: 10 Stunden Beratung à 120 €.“
„Buche diese Banktransaktion auf Sachkonto 4400.“
„Lade diesen PDF-Beleg hoch und ordne ihn der passenden Transaktion zu.“
„Zeig mir meine Kreditoren und leg einen neuen für unseren Hosting-Anbieter an.“
„Erstelle mir die BWA für das letzte Quartal und zeig mir das Kontenblatt zu Konto 4400.“
Die Tools werden automatisch aus der offiziellen API generiert und in 🟢 nur lesend, 🟡 schreibend und 🔴 destruktiv gruppiert — ein gut umgesetzter Host kann jede Gruppe unterschiedlich behandeln.
Funktionsweise
Claude / Cursor / beliebiger MCP-Client ──MCP──► dieser Server ──HTTPS──► BuchhaltungsButler API (Cloud)Der Server liest die mitgelieferte OpenAPI-Spec ein und macht daraus MCP-Tools (inklusive
Auflösung von $ref-Batch-Payloads und Entfernen von HTML aus den Beschreibungen),
versieht jedes Tool mit seiner Sicherheitskategorie und hängt deine Basic-Auth-Credentials
sowie den api_key an jede ausgehende Anfrage. Deine Zugangsdaten bleiben in der
Server-Umgebung — das Modell sieht sie nie und fasst sie nie an.
Voraussetzungen
Ein BuchhaltungsButler-Konto mit API-Zugang — ein API Client + API Secret (Einstellungen → API) sowie ein Kunden-
api_key(siehe API-Zugangsdaten besorgen).Docker (Docker Desktop unter macOS/Windows) für den Schnellstart unten — oder Node.js ≥ 18, um aus dem Quellcode zu starten.
Schnellstart (Docker)
1. Zugangsdaten hinterlegen. Beispielkonfiguration kopieren und ausfüllen:
cp .env.example .env
# .env bearbeiten → BB_API_CLIENT, BB_API_SECRET, BB_API_KEY setzen
# → MCP_AUTH_TOKEN setzen. PFLICHT, sonst startet der Server
# nicht, denn .env.example bindet auf 0.0.0.0:
# openssl rand -hex 322. Server starten:
docker compose up -d --build3. Prüfen, ob er läuft:
curl -s http://localhost:3000/health # → {"status":"ok","server":"buchhaltungsbutler-mcp"}4. MCP-Client verbinden. Entfernte Endpunkte werden in Claude als Custom Connector
hinzugefügt (Einstellungen → Connectors) oder lokal mit
mcp-remote gebrückt. Trage Folgendes unter
mcpServers in deiner Client-Konfiguration ein und starte die App danach vollständig neu:
{
"mcpServers": {
"buchhaltungsbutler": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:3000/mcp",
"--header", "Authorization: Bearer DEIN_MCP_AUTH_TOKEN"
]
}
}
}(Die --header-Zeile entfällt nur, wenn du ohne Token auf Loopback bindest.
Im Docker-Schnellstart oben ist das Token Pflicht.)
Lieber ein fertiges Image?
Jeder Push auf main veröffentlicht ein startbereites Image in der GitHub Container
Registry — damit kannst du den lokalen Build komplett überspringen:
docker run -d --name buchhaltungsbutler-mcp -p 3000:3000 --env-file .env \
ghcr.io/ohneben/buchhaltungsbutler-mcp:latestAPI-Zugangsdaten besorgen
BuchhaltungsButler nutzt zwei Authentifizierungsebenen (siehe die offizielle Dokumentation):
HTTP-Basic-Auth — ein API Client + API Secret, deine globalen API-Zugangsdaten. Zu finden bzw. anzulegen in BuchhaltungsButler unter Einstellungen → API.
api_key— legt fest, auf welches Kundenkonto sich eine Anfrage bezieht. Er steht in den Firmendaten-Einstellungen des jeweiligen Kunden.
Trage alle drei Werte in .env ein. Der Server hängt sie an jede Anfrage an, dein
Assistent bekommt sie also nie zu sehen. Ein einzelner Tool-Aufruf kann optional einen
eigenen api_key mitgeben, um ein anderes Kundenkonto anzusprechen.
Konfiguration
Alles wird in .env gesetzt (kopiert aus .env.example):
Variable | Pflicht | Standard | Beschreibung |
| ✅ | — | API Client (Basic-Auth-Benutzername) |
| ✅ | — | API Secret (Basic-Auth-Passwort) |
| ✅ | — | Standard-Kunden- |
| — |
|
|
| — |
| HTTP-Port, auf dem gelauscht wird |
| — |
| HTTP-Bind-Adresse |
| — |
| HTTP-Route für MCP |
| ⚠️ | (aus) | Verlangt |
| — | (automatisch) | Erlaubte |
| — | (aus) | Hebt die Startverweigerung ohne Token auf. Nur für nachweislich unerreichbare Endpunkte |
| — |
| Sekunden Leerlauf, bevor eine Session verworfen wird |
| — |
| Obergrenze gleichzeitiger Sessions |
| — | (aus) | Erlaubt einem Tool-Aufruf, den |
| — |
| Clientseitiges Limit an Anfragen pro Minute |
| — |
| Gesamtbudget eines Lese-Tools in Millisekunden, über alle Versuche. Liegt unter den 60 s, nach denen der SDK-Client aufgibt |
| — |
| Weitere Versuche eines Lese-Tools nach Timeout, Netzwerkfehler oder HTTP 429/502/503/504 (max. 5), solange das Budget reicht. Bricht der Client ab, startet kein weiterer Versuch. Schreib-Tools werden nie wiederholt und haben kein Timeout |
| — | (aus der Spec) | Überschreibt die Basis-URL der API |
Nach Änderungen an .env neu laden mit docker compose up -d --force-recreate.
Toolnamen
Jedes Tool heißt <ressource>_<verb>. Die Verben sind fest: list, get,
create, update, delete, upload, assign, unassign, unconfirm,
restore, cancel. Damit heißt dieselbe Sache überall gleich, unabhängig
davon, wie der jeweilige BB-Pfad geschrieben ist (die API mischt add und
create, und zwei Batch-Pfade sind camelCase).
Anlegen geht immer über ein Tool, das eine Liste nimmt. receipts_create
legt einen Beleg oder hundert an, ein einzelner Datensatz ist eine Liste mit
einem Eintrag. Deshalb gibt es 46 Tools für 54 Endpunkte: acht
Einzel-Endpunkte sind in ihrem Batch-Gegenstück aufgegangen.
Alte Namen bleiben aufrufbar
Die Namen bis 1.1.1 funktionieren weiter. Sie stehen nicht mehr im Katalog,
werden aber beim Aufruf aufgelöst, damit fest verdrahtete Aufrufe aus
älteren Releases nicht ins Leere laufen. Ein Aufruf von receipts_add mit
Einzelfeldern landet weiterhin auf /receipts/add.
BB_READ_ONLY und BB_TOOL_ALLOWLIST greifen vorher: über einen alten Namen
lässt sich kein Tool erreichen, das die Policy ausschließt.
Alt (bis 1.1.1) | Neu |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Die vollständige Zuordnung steht in src/naming.ts.
Sicherheitskategorien der Tools
Jede Tool-Beschreibung beginnt mit einem dieser Banner und trägt die passenden MCP-Annotationen:
Banner | Anzahl |
|
| Bedeutung |
🟢 READ-ONLY | 15 |
|
| Ruft nur Daten ab. Ungefährlich. |
🟡 WRITE · legt Daten an | 17 |
|
| Erzeugt Datensätze (nicht idempotent, mehrfach aufgerufen entstehen Duplikate). |
🟡 WRITE · ändert Daten | 4 |
|
| Aendert bestehende Stammdaten direkt. |
🟡 WRITE · verknüpft/löst | 3 |
|
| Ordnet Beleg und Transaktion zu bzw. hebt die Zuordnung auf. Umkehrbar. |
🟡 WRITE · nimmt Zustand zurück | 4 |
|
| Setzt Buchungen auf unbestätigt / stellt Belege wieder her. Umkehrbar. |
🔴 DESTRUCTIVE · löscht | 3 |
|
| Löscht oder storniert einen Datensatz. Vorher bestätigen lassen. |
Hosts, die Annotationen respektieren (Claude gehört dazu), können für
destructiveHint-Tools eine Bestätigung verlangen und readOnlyHint-Tools
automatisch vertrauen.
Jedes Tool bringt zusätzlich ein outputSchema mit, also die Form der
Erfolgsantwort. Erfolgreiche Aufrufe liefern die Antwort deshalb nicht nur als
Text, sondern auch als structuredContent.
Mit
npm run list-tools(ohne Zugangsdaten) lässt sich der vollständige Katalog jederzeit ausgeben.
Tool | Endpunkt |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tools mit zwei Endpunkten nehmen eine Liste. Kommt der Aufruf stattdessen mit Einzelfeldern, geht er an den Einzel-Endpunkt.
Tool | Endpunkt | Einzel-Endpunkt |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
|
| |
|
| |
|
|
|
Tool | Endpunkt | Unterkategorie |
|
| ändert |
|
| ändert |
|
| ändert |
|
| ändert |
|
| verknüpft |
|
| verknüpft |
|
| verknüpft |
|
| nimmt zurück |
|
| nimmt zurück |
|
| nimmt zurück |
|
| nimmt zurück |
Tool | Endpunkt | Hinweis |
|
| Wiederherstellbar über |
|
| Nicht wiederherstellbar |
|
| Noch nicht festgeschriebene Buchungen werden gelöscht; festgeschriebene werden durch eine Stornobuchung ausgeglichen |
Was die v1-API nicht kann
Diese Lücken stehen absichtlich auch in den Tool-Beschreibungen, damit das Modell nicht nach einem Endpunkt sucht, den es nicht gibt:
Ressource | Fehlt |
Kreditoren, Debitoren, Buchungskonten | kein Löschen |
Konten ( | kein Aendern, kein Löschen |
Kommentare | kein Lesen, kein Aendern, kein Löschen |
Rechnungen | kein Lesen, kein Aendern, kein Stornieren |
Transaktionen | kein Aendern, kein Löschen |
Aus dem Quellcode starten (stdio, ohne Docker)
Du bevorzugst den klassischen stdio-Modus für Claude Desktop? Dann lokal bauen:
npm install
npm run buildAnschließend Claude Desktop in claude_desktop_config.json auf den kompilierten
Einstiegspunkt zeigen lassen:
{
"mcpServers": {
"buchhaltungsbutler": {
"command": "node",
"args": ["/ABSOLUTER/PFAD/Buchhaltungsbutler MCP/dist/index.js"],
"env": {
"MCP_TRANSPORT": "stdio",
"BB_API_CLIENT": "dein-api-client",
"BB_API_SECRET": "dein-api-secret",
"BB_API_KEY": "dein-kunden-api-key"
}
}
}
}Oder den Container stattdessen über stdio betreiben:
{
"mcpServers": {
"buchhaltungsbutler": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT=stdio",
"-e", "BB_API_CLIENT", "-e", "BB_API_SECRET", "-e", "BB_API_KEY",
"buchhaltungsbutler-mcp:latest"
],
"env": {
"BB_API_CLIENT": "dein-api-client",
"BB_API_SECRET": "dein-api-secret",
"BB_API_KEY": "dein-kunden-api-key"
}
}
}
}(Das Image vorher bauen: docker build -t buchhaltungsbutler-mcp:latest .)
Spec aktuell halten
Die mitgelieferte spec.json ist die offizielle BuchhaltungsButler-v1-OpenAPI-Spec — die
maßgebliche Quelle für die Tools. So aktualisierst du sie auf einen neueren API-Stand:
curl -s https://app.buchhaltungsbutler.de/docs/api/v1.de.json -o spec.json
npm run buildNeue Pfade werden automatisch übernommen; trage sie in PATH_CATEGORY in
src/categories.ts ein, damit sie die richtige Sicherheitskategorie bekommen (nicht
zugeordnete Pfade fallen konservativ auf die Kategorie create zurück).
Hinweis zur Versionsnummer: BuchhaltungsButler pflegt das Feld
info.versionin der Spec nicht zuverlässig — der Inhalt kann sich ändern, ohne dass die Nummer steigt. Verlass dich beim Abgleich also nicht auf die Version, sondern vergleiche die Pfadliste (paths) und die Parameter der Endpunkte.
Entwicklung
Hinweise zu korrigierten Buchungs- und Zuordnungsantworten, Teilfehlern und unklarem Schreibausgang: Belege buchen und Zahlungen zuordnen.
npm install
npm run build # TypeScript → dist/ kompilieren
npm test # Vitest-Suite ausführen
npm run list-tools # kategorisierten Tool-Katalog ausgeben (ohne Zugangsdaten)Die CI baut und testet jeden Push unter Node 20 und 22; Pushes auf main veröffentlichen
zusätzlich ein Docker-Image in der GitHub Container Registry.
Für eine ergänzende Prüfung mit einem eigenen API-Zugang siehe Lesende API-/MCP-Verifikation. Die normale Testsuite verwendet synthetische Daten und benötigt keine Zugangsdaten.
Hinweise & Konventionen
Datumsangaben:
YYYY-MM-DD. Beträge: Punkt als Dezimaltrennzeichen (z. B.-12.30).Datei-Uploads (
receipts_upload): Die Datei wird als Base64-Zeichenkette im Feldfileübergeben.receipts_createlegt Belege ohne Datei an.Blättern: Die meisten
list-Tools akzeptierenlimitundoffset. Bei den geprüften Beleg-, Transaktions- und Buchungslisten zähltrowsnur die aktuelle Seite, nicht den Gesamtbestand. Wiederholte IDs und fehlenden Fortschritt erkennen. Eine leere Abschlussseite und Deduplizierung beweisen keine Vollständigkeit: gefilterte Transaktionsseiten haben sich im Praxistest überschnitten, während andere IDs fehlten. Fürtransactions_listbevorzugtid_by_customer_frommit konstanten Filtern undlimit, ohneoffset, nutzen: Der Cursor ist exklusiv und erzwingt aufsteigende ID-Sortierung. Bei 0 beginnen, anschließend die größte erhaltene ID unverändert als nächsten Cursor setzen; IDs und Fortschritt prüfen, bis zur leeren Seite fortsetzen und unabhängig abstimmen. Details und Grenzen: lesende Verifikation.Einzelabrufe:
receipts_get_by_idundtransactions_get_by_idbenötigenid_by_customerals positive ganze Zahl aus dem jeweiligen Listentool. Der Server setzt diese Nummer in den API-Pfad ein.Anlegen geht immer über ein Tool, das ein Array nimmt; die Item-Schemata werden aus den Spec-Definitionen aufgelöst und dem Modell mitgegeben. Ein einzelner Datensatz ist ein Array mit einem Eintrag.
Auswertungen (BWA, Summen- und Saldenliste) werden asynchron im Hintergrund erzeugt: erst
reports_create_*aufrufen, dannreports_get_*mit der zurückgegebenenid_by_customer. Eine neue Auswertung desselben Typs ersetzt die vorherige.Kontenblatt:
reports_get_sums_ledgerbenötigt nur Buchungskontonummer und Zeitraum; die API liefert es direkt, ohne vorher erzeugte SuSa und ohne Berichts-ID.Rate-Limit: BuchhaltungsButler erlaubt 100 Anfragen/Kunde/Minute; der Server drosselt sich selbst bei
BB_RATE_LIMIT(Standard 90), um sicher darunter zu bleiben.
Sicherheit
Deine API-Zugangsdaten liegen ausschließlich in
.env, und diese Datei ist von Git ausgeschlossen. Committe niemals echte Geheimnisse. Falls doch etwas abfließt, rotiere die Daten unter BuchhaltungsButler → Einstellungen → API.Der HTTP-Endpunkt verlangt ein Token, sobald er über Loopback hinaus gebunden ist. Ohne
MCP_AUTH_TOKENverweigert der Server den Start und erklärt im Fehlertext, was zu tun ist. Sende das Token alsAuthorization: Bearer <Token>-Header, idealerweise hinter TLS.Auch auf localhost gilt: ohne Token wird der
Host-Header auf localhost-Namen begrenzt, damit keine beliebige Webseite den Endpunkt per DNS-Rebinding ansprechen kann. Hinter einem Reverse-Proxy setzt du dafürMCP_ALLOWED_HOSTS.Hinter einem Reverse-Proxy setzt du den
Host-Header im Proxy am besten fest auf den internen Upstream-Namen und trägst genau diesen inMCP_ALLOWED_HOSTSein. Dann hängt die Prüfung nicht an der öffentlichen Domain und übersteht einen Domainwechsel. (Tipp von @WinFuture23.)Setzt du
MCP_ALLOWED_HOSTSund hat deine Plattform einen HTTP-Health-Check, muss dessen Hostname mit in die Liste. Railway sendetHost: healthcheck.railway.app, Kubernetes-Probes fragen je nach Konfiguration über die Container-IP an. Fehlt der Name, bekommt der Health-Check eine 403 und die Plattform wertet das Deployment als kaputt./healthliegt hinter der Host-Prüfung, aber vor der Token-Prüfung: ein Health-Check der Plattform braucht kein Token. Zusätzlich akzeptiert/healthimmerlocalhost,127.0.0.1und[::1], damit derHEALTHCHECKaus dem mitgelieferten Dockerfile weiterläuft, wenn duMCP_ALLOWED_HOSTSauf deine öffentliche Domain setzt. Fragt dein Health-Check dagegen über die Container-IP oder einen Service-Namen an, musst du diesen Namen inMCP_ALLOWED_HOSTSaufnehmen.Der
api_keypro Tool-Aufruf ist standardmäßig deaktiviert (BB_ALLOW_API_KEY_OVERRIDE=1schaltet ihn frei), damit das Modell nicht selbst entscheiden kann, auf welchen Mandanten geschrieben wird.
Die vollständige Richtlinie und den Meldeweg für Sicherheitslücken findest du in SECURITY.md.
Credits & Lizenz
Eine inoffizielle Community-Integration für BuchhaltungsButler; weder mit BuchhaltungsButler verbunden noch von dort unterstützt. Basiert auf dem Model Context Protocol. Veröffentlicht unter der MIT-Lizenz.
Available Tools
46 toolsaccounts_createAccounts: add a basic accountA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add a basic account
Use to register a new bank, cash or credit-card account before importing transactions for it.
Not for chart-of-accounts entries. To add a posting account number, use postingaccounts_create.
Not idempotent: calling twice with the same name creates two accounts. Check accounts_list first. v1 offers no way to update or delete an account afterwards.
Endpoint: POST /accounts/add
Inputs: name (required), type (required), postingaccount_number (required), is_revision_safe, +1 more. Returns: message, success, postingaccount_number
accounts_listAccounts: get all the accountsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get all the accounts
Use to list the bank, cash and credit-card accounts that transactions can be booked against, e.g. to resolve an account name to the numeric account id the transaction tools expect.
Not the chart of accounts. For posting account numbers such as 1200 or 4400, use postingaccounts_list.
v1 offers no update or delete endpoint for accounts. An account created here can only be listed afterwards.
Endpoint: POST /accounts/get
Inputs: no named parameters. Returns: data, rows, message, success
comments_createComments: add comment to transaction or receiptA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add comment to transaction or receipt
Add comment to transaction or receipt. NOTE: You have to submit either a transaction_id_by_customer or a receipt_id_by_customer.
Use to attach a free-text note to one receipt or one transaction, for example to record why a booking was categorised the way it was.
Exactly one of transaction_id_by_customer or receipt_id_by_customer must be set. v1 offers no endpoint to read, edit or delete comments, so a comment written here can only be seen in the BuchhaltungsButler web app.
Endpoint: POST /comments/add
Inputs: comment_text (required), receipt_id_by_customer, transaction_id_by_customer. Returns: message, success
cost_locations_createCost Locations: add cost locationA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add cost location
Add a new cost location.
Use to create a cost centre before referencing it from a posting.
Not idempotent. Check cost_locations_list first to avoid a duplicate.
Endpoint: POST /cost-locations/add
Inputs: code (required), name (required). Returns: code, message, success
cost_locations_deleteCost Locations: delete cost locationADestructiveIdempotent
🔴 DESTRUCTIVE · deletes data: Deletes or cancels a record. Confirm with the user before calling. Receipt deletes are restorable; cost-location deletes are not. Cancelling a posting deletes it if it is not yet fixed, otherwise it books a reversal posting.
delete cost location
Delete a cost location.
Use to remove a cost centre that is no longer needed.
Permanent. Unlike a deleted receipt there is no restore endpoint, so confirm with the user before calling.
Endpoint: POST /cost-locations/delete
Inputs: code (required). Returns: message, success
cost_locations_listCost Locations: get cost locationsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get cost locations
Get cost locations for a specified customer account. The response includes the number of returned rows and an array of cost locations data. NOTE: Each request is limited to 1000 cost locations!
Use to list the cost centres available for the cost_location fields on the posting tools.
Endpoint: POST /cost-locations/get
Inputs: code, limit, offset. Returns: data, rows, message, success
cost_locations_updateCost Locations: update cost locationAIdempotent
🟡 WRITE · updates data: Modifies existing master data in place.
update cost location
Update a cost location's name/description.
Use to rename an existing cost centre or change its number.
Overwrites the fields you send. Read the current record with cost_locations_list first if you intend a partial change.
Endpoint: POST /cost-locations/update
Inputs: code (required), name (required). Returns: message, success
creditors_createSettings: create creditorA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create creditor
Create a creditor account.
Use to create one or more suppliers.
For customers you invoice, use debtors_create.
Takes one or many: pass an array of creditors in creditors. A single record is an array of one.
Not idempotent: check creditors_list first, since a repeated call creates duplicate suppliers. v1 offers no delete endpoint, so a creditor created here can only be updated afterwards, never removed.
Endpoint: POST /settings/add-batch/creditors
Inputs: creditors (required). Returns: errors, success, creditors
creditors_listSettings: get creditorsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get creditors
Get all creditors
Use to list suppliers, for example to resolve a supplier name to the creditor id the receipt and posting tools expect.
For customers you invoice, use debtors_list.
Supports limit and offset. Do not assume rows is the grand total. Continue paging until empty and check progress. v1 offers no delete endpoint for creditors, so they can only be created, listed and updated.
Endpoint: POST /settings/get/creditors
Inputs: limit, offset. Returns: data, rows, message, success
creditors_updateSettings: update creditorAIdempotent
🟡 WRITE · updates data: Modifies existing master data in place.
update creditor
Update a creditor account.
Use to change a supplier's address, bank details or payment terms.
Overwrites the fields you send. Read the current record with creditors_list first if you intend a partial change.
Endpoint: POST /settings/update/creditor
Inputs: postingaccount_number (required), bic, zip, city, +9 more. Returns: data, message, success
debtors_createSettings: create debtorA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create debtor
Create a debtor account.
Use to create one or more customers.
For suppliers you buy from, use creditors_create.
Takes one or many: pass an array of debtors in debtors. A single record is an array of one.
Not idempotent: check debtors_list first. v1 offers no delete endpoint, so a debtor created here can only be updated afterwards, never removed.
Endpoint: POST /settings/add-batch/debtors
Inputs: debtors (required). Returns: errors, debtors, success
debtors_listSettings: get debitorsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get debitors
Get all debitors
Use to list customers, for example to resolve a customer name to the debtor id the receipt and posting tools expect.
For suppliers you buy from, use creditors_list.
Supports limit and offset. v1 offers no delete endpoint for debtors, so they can only be created, listed and updated.
Endpoint: POST /settings/get/debtors
Inputs: limit, offset. Returns: data, rows, message, success
debtors_updateSettings: update debtorAIdempotent
🟡 WRITE · updates data: Modifies existing master data in place.
update debtor
Update a debtor account.
Use to change a customer's address, bank details or customer number.
Overwrites the fields you send. Read the current record with debtors_list first if you intend a partial change.
Endpoint: POST /settings/update/debtor
Inputs: postingaccount_number (required), bic, zip, city, +9 more. Returns: data, message, success
invoices_createInvoices: create invoiceA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create invoice
Add an invoice for the specified customer.
Use to issue a final outgoing invoice that is booked immediately.
For an invoice that should stay editable, use invoices_create_draft. For a structured XML invoice in XRechnung or ZUGFeRD format, use invoices_create_e_invoice.
Not idempotent: a second call issues a second invoice with a new number. v1 offers no endpoint to list, change or cancel an invoice once created.
Endpoint: POST /invoices/create
Inputs: date (required), type (required), item_vat (required), item_name (required), +28 more. Returns: message, success, file_name, invoicenumber, +1 more
invoices_create_draftInvoices: create invoice draftA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create invoice draft
Add an invoice draft for the specified customer.
Use to prepare an invoice that a human should review and release in the BuchhaltungsButler web app.
A draft is not booked and carries no invoice number. To issue a final invoice directly, use invoices_create.
v1 offers no endpoint to list, edit or release drafts. Releasing happens in the web app.
Endpoint: POST /invoices/create/draft
Inputs: date (required), type (required), item_vat (required), item_name (required), +25 more. Returns: message, success
invoices_create_e_invoiceInvoices: create e-invoiceA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create e-invoice
Add an e-invoice for the specified customer.
Use when the recipient requires a structured electronic invoice, for example a German public-sector customer expecting XRechnung.
For an ordinary PDF invoice, use invoices_create.
Not idempotent. v1 offers no endpoint to list or cancel an e-invoice once created.
Endpoint: POST /invoices/create/e-invoice
Inputs: zip (required), city (required), date (required), type (required), +30 more. Returns: message, success, file_name, invoicenumber, +1 more
postingaccounts_createSettings: add postingaccountA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add postingaccount
Create a postingaccount.
Use to add an account number to the chart of accounts that the standard chart does not cover.
To register a bank or cash account, use accounts_create.
Not idempotent. v1 offers no delete endpoint, so a posting account created here can only be updated afterwards.
Endpoint: POST /settings/add/postingaccount
Inputs: name (required), postingaccount_number (required), parent_postingaccount_number (required). Returns: message, success, postingaccount_number, parent_postingaccount_number
postingaccounts_listSettings: get postingaccountsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get postingaccounts
Get all postingaccounts
Use to list the chart of accounts, for example to find the posting account number for office supplies before booking.
Not bank accounts. For the bank, cash and credit-card accounts transactions belong to, use accounts_list.
Supports limit and offset; a full SKR chart runs to several hundred rows. Do not assume rows is the grand total: continue paging until empty and check progress, or filter instead. v1 offers no delete endpoint for posting accounts.
Endpoint: POST /settings/get/postingaccounts
Inputs: limit, order, offset, exclude_debtors, +3 more. Returns: data, rows, message, success
postingaccounts_updateSettings: update postingaccountAIdempotent
🟡 WRITE · updates data: Modifies existing master data in place.
update postingaccount
Update a postingaccount.
Use to rename a posting account or change its properties.
Overwrites the fields you send. Read the current record with postingaccounts_list first if you intend a partial change.
Endpoint: POST /settings/update/postingaccount
Inputs: name (required), postingaccount_number (required). Returns: data, message, success
postings_assign_receipt_to_freePostings: assign receipt to free postingA
🟡 WRITE · links/unlinks records: Creates or removes an assignment between records (e.g. receipt ↔ transaction). Reversible.
assign receipt to free posting
Assign a receipt to a free posting.
Use to attach a receipt to a free posting that was booked without one, so the entry has its supporting document.
To link a receipt to a bank transaction rather than a posting, use transactions_assign_receipts.
Endpoint: POST /postings/assign/receipt-to-free-posting
Inputs: posting_id_by_customer (required), receipt_id_by_customer (required). Returns: message, success
postings_cancelPostings: cancel postingADestructiveIdempotent
🔴 DESTRUCTIVE · deletes data: Deletes or cancels a record. Confirm with the user before calling. Receipt deletes are restorable; cost-location deletes are not. Cancelling a posting deletes it if it is not yet fixed, otherwise it books a reversal posting.
cancel posting
Cancel a specified posting. Postings that are not fixed are deleted, fixed postings are cancelled by creating a reversal posting.
Use to take a booking out of the books entirely.
This is stronger than the postings_unconfirm_* tools: those keep the posting and only clear its confirmation, this one removes or reverses it. Prefer unconfirming when the goal is to edit and rebook.
The effect depends on the posting: one that is not yet fixed is deleted outright, a fixed one stays and is offset by a reversal posting, which leaves two visible entries in the journal. Confirm with the user before calling.
Endpoint: POST /postings/cancel
Inputs: posting_id_by_customer (required). Returns: message, success
postings_create_for_receiptPostings: add receipt postingA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add receipt posting
Add postings for a specified receipt. Important: Receipt postings are only available if creditor or debtor posting is activated!
IMPORTANT: If you add postings to a receipt with foreign currency, you have to get that receipt (/receipts/get/id_by_customer) and find the calculated amount before performing this request.
Use to book one or more receipts that already exist in BuchhaltungsButler, splitting each across posting accounts, VAT rates and cost centres.
For a journal entry with no receipt behind it, use postings_create_free.
Takes one or many: pass an array of receipts in receipts. A single record is an array of one.
The per-receipt arrays (postingaccounts, amounts, vats, postingtexts) are positional: index 0 of each describes the same split line, so they must all have the same length. Not idempotent. Reversible with postings_unconfirm_for_receipt while the posting is not fixed.
Endpoint: POST /postings/add-batch/receipts
Inputs: receipts (required). Returns: errors, success, receipts
postings_create_for_transactionPostings: add transaction postingA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add transaction posting
Add postings for a specified transaction.
Use to book one or more bank transactions, splitting each across posting accounts, VAT rates and cost centres.
For a journal entry with no bank transaction behind it, use postings_create_free.
Takes one or many: pass an array of transactions in transactions. A single record is an array of one.
The per-transaction arrays are positional and must all have the same length. Not idempotent. Reversible with postings_unconfirm_for_transaction while the posting is not fixed.
Endpoint: POST /postings/add-batch/transactions
Inputs: transactions (required). Returns: errors, success, transactions
postings_create_freePostings: add free postingA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add free posting
Add a free posting.
Use to book a debit/credit pair that is not tied to an existing receipt or bank transaction, such as a manual accrual or a correction.
If the booking documents a receipt, use postings_create_for_receipt. If it settles a bank transaction, use postings_create_for_transaction.
Takes one or many: pass an array of free postings in free_postings. A single record is an array of one.
A "free" posting is BuchhaltungsButler's term for a standalone journal entry: you name both sides yourself via postingaccount_debit and postingaccount_credit. Not idempotent, so a repeated call books the amount twice. A receipt can be attached afterwards with postings_assign_receipt_to_free.
Endpoint: POST /postings/add-batch/free
Inputs: free_postings (required). Returns: errors, success, free_postings
postings_listPostings: get postingsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get postings
Get postings for a specified customer account. The response includes the number of returned rows and an array of postings data. NOTE: Each request is limited to 1000 postings!
Use to read the booking journal, filtered by date range or posting account.
Supports limit and offset. Ask for a bounded date range rather than paging through a whole financial year.
Endpoint: POST /postings/get
Inputs: date_to (required), date_from (required), limit, order, +7 more. Returns: data, rows, message, success
postings_unconfirm_for_receiptPostings: unconfirm receipt postingAIdempotent
🟡 WRITE · reverts state: Reverts a prior state change (un-confirm a posting, restore a deleted receipt). Reversible.
unconfirm receipt posting
Remove postings for a specified receipt by unconfirming them. This will only work if the postings are not fixed.
Use to send a receipt posting back to the unconfirmed state so it can be corrected.
This keeps the posting and only clears its confirmation. To remove the posting itself, use postings_cancel.
Only works while the posting is not fixed.
Endpoint: POST /postings/unconfirm/receipt
Inputs: receipt_id_by_customer (required). Returns: message, success
postings_unconfirm_for_transactionPostings: unconfirm transaction postingAIdempotent
🟡 WRITE · reverts state: Reverts a prior state change (un-confirm a posting, restore a deleted receipt). Reversible.
unconfirm transaction posting
Remove postings for a specified transaction by unconfirming them. This will only work if the postings are not fixed.
Use to send a transaction posting back to the unconfirmed state so it can be corrected.
This keeps the posting and only clears its confirmation. To remove the posting itself, use postings_cancel.
Only works while the posting is not fixed.
Endpoint: POST /postings/unconfirm/transaction
Inputs: transaction_id_by_customer (required). Returns: message, success
postings_unconfirm_freePostings: unconfirm free postingAIdempotent
🟡 WRITE · reverts state: Reverts a prior state change (un-confirm a posting, restore a deleted receipt). Reversible.
unconfirm free posting
Remove a specified free posting by unconfirming it. This will only work if the posting is not fixed.
Use to send a free posting back to the unconfirmed state so it can be corrected.
This keeps the posting and only clears its confirmation. To remove the posting itself, use postings_cancel.
Only works while the posting is not fixed. Fixed postings can no longer be unconfirmed.
Endpoint: POST /postings/unconfirm/free
Inputs: posting_id_by_customer (required). Returns: message, success
receipts_createReceipts: add a receiptA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add a receipt
Add a receipt into the specified customer account. NOTE: Use this endpoint, to add a receipt without a file!
Use to record receipts that have no file attached, for example when the document lives in another system.
If you have the actual PDF or image, use receipts_upload instead so BuchhaltungsButler can read the document and pre-fill its data.
Takes one or many: pass an array of receipts in receipts. A single record is an array of one.
Not idempotent: a repeated call creates duplicate receipts. The response reports per-item success, so a partial failure leaves the successful entries in place.
Endpoint: POST /receipts/addBatch
Inputs: receipts (required). Returns: errors, success, receipts
receipts_deleteReceipts: delete receipt by id_by_customerADestructiveIdempotent
🔴 DESTRUCTIVE · deletes data: Deletes or cancels a record. Confirm with the user before calling. Receipt deletes are restorable; cost-location deletes are not. Cancelling a posting deletes it if it is not yet fixed, otherwise it books a reversal posting.
delete receipt by id_by_customer
Mark a receipt as deleted for a specified customer account by id_by_customer. You can get the "id_by_customer" by using the "/receipts/get method" first.
Use to remove a receipt that was filed by mistake.
Recoverable: receipts_restore brings the receipt back. Confirm with the user before calling.
Endpoint: POST /receipts/delete/id_by_customer
Inputs: id_by_customer (required). Returns: message, success, id_by_customer
receipts_get_by_idReceipts: get receipt by id_by_customerARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get receipt by id_by_customer
Get a single receipt for a specified customer account by id_by_customer. You can get the "id_by_customer" by using the "/receipts/get method" first. The response includes an array of receipt data.
Use to fetch a single receipt whose id you already have.
To search or page through receipts, use receipts_list.
id_by_customer is the per-customer counter shown in the BuchhaltungsButler UI, not a global database id.
Endpoint: POST /receipts/get/id_by_customer
Inputs: id_by_customer (required), get_file. Returns: data, message, success
receipts_listReceipts: get receiptsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get receipts
Get receipts for a specified customer account. The response includes the number of returned rows and an array of receipts data.
Use to search receipts by direction, date range or payment status.
To fetch one known receipt, use receipts_get_by_id.
list_direction is required and selects inbound or outbound receipts. Supports limit and offset; observed rows counts only the returned page. Continue paging until empty, deduplicate IDs and check progress.
Endpoint: POST /receipts/get
Inputs: list_direction (required), limit, order, offset, +9 more. Returns: data, rows, message, success
receipts_list_assigned_transactionsReceipts: get all transactions assigned to a specific receiptARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get all transactions assigned to a specific receipt
Get all transactions assigned to a specific receipt for a specified customer account by id_by_customer. You can get the "id_by_customer" by using the "/receipts/get method" first.
Use to see which bank transactions are linked to a given receipt, for example to check whether an invoice has been matched to a payment.
For the opposite direction, use transactions_list_assigned_receipts.
Endpoint: POST /receipts/assigned-transactions/get
Inputs: receipt_id_by_customer (required), confirmed_only. Returns: data, rows, message, success
receipts_restoreReceipts: restore deleted receipt by id_by_customerAIdempotent
🟡 WRITE · reverts state: Reverts a prior state change (un-confirm a posting, restore a deleted receipt). Reversible.
restore deleted receipt by id_by_customer
Restore a marked as deleted receipt for a specified customer account by id_by_customer. You can get the "id_by_customer" by using the "/receipts/get method" first.
Use to bring back a receipt that was deleted with receipts_delete.
Endpoint: POST /receipts/restore/id_by_customer
Inputs: id_by_customer (required). Returns: message, success, id_by_customer
receipts_uploadReceipts: upload receiptA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
upload receipt
Upload a receipt into the specified customer account. The receipt will be processed by the BuchhaltungsButler technology. The response includes the filename (without extension) of the receipt as it is stored.
Note: max 10 requests per minute
Use to send the actual receipt file. BuchhaltungsButler runs document recognition on it and returns the stored filename.
To record a receipt without a file, use receipts_create.
Rate limited to 10 requests per minute. Not idempotent, so uploading the same file twice creates two receipts.
Endpoint: POST /receipts/upload
Inputs: file (required), type (required), date, amount, +11 more. Returns: message, success, filename, id_by_customer
reports_create_bwaReports: create bwa reportA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create bwa report
Triggers the creation of a BWA report ("Betriebswirtschaftliche Auswertung").
The report is generated asynchronously in the background. The response contains the id_by_customer of the created report, which may be used to retrieve it once the generation has been finished.
A new report may only be requested once the generation of a previously requested report of the same type has been finished.
Use to request a BWA (Betriebswirtschaftliche Auswertung, the German management report). Step one of two.
This only triggers generation. To read the finished report, call reports_get_bwa afterwards.
Runs asynchronously and returns an id, not the report. A new BWA can only be requested once the previous one has finished, and it replaces the previous one.
Endpoint: POST /reports/create/bwa
Inputs: date_to (required), date_from (required). Returns: message, success, id_by_customer
reports_create_sumsReports: create sums reportA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
create sums report
Triggers the creation of a sums report ("Summen- und Saldenliste"). The report is always created for all of the customer's postingaccounts.
The report is generated asynchronously in the background. The response contains the id_by_customer of the created report, which may be used to retrieve it once the generation has been finished.
A new report may only be requested once the generation of a previously requested report of the same type has been finished.
Use to request a sums and balances report (Summen- und Saldenliste). Step one of two.
To read the finished report, call reports_get_sums afterwards.
Runs asynchronously and returns an id. A new report may only be requested once the previous one has finished, and it replaces the previous one.
Endpoint: POST /reports/create/sums
Inputs: date_to (required), date_from (required), base, file_csv, +2 more. Returns: message, success, id_by_customer
reports_get_bwaReports: get bwa reportARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get bwa report
Returns a previously created BWA report ("Betriebswirtschaftliche Auswertung").
Reports are generated asynchronously, so a report is only available once its generation has been finished. Note that creating a new report of the same type replaces the previously created one.
Use to read a BWA that reports_create_bwa has finished generating. Step two of two.
Returns nothing useful until generation has finished. If the report is not ready, wait and retry rather than requesting a new one, since a new request replaces the pending one.
Endpoint: POST /reports/get/bwa
Inputs: report_id_by_customer (required), get_files. Returns: files, report, message, success
reports_get_sumsReports: get sums reportARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get sums report
Returns a previously created sums report ("Summen- und Saldenliste").
Reports are generated asynchronously, so a report is only available once its generation has been finished. Note that creating a new report of the same type replaces the previously created one.
Use to read a sums and balances report that reports_create_sums has finished generating. Step two of two.
For the individual bookings behind one posting account, use reports_get_sums_ledger.
Endpoint: POST /reports/get/sums
Inputs: report_id_by_customer (required), get_files. Returns: files, report, message, success
reports_get_sums_ledgerReports: get sums report postingaccount ledgerARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get sums report postingaccount ledger
Returns the postingaccount ledger ("Kontenblatt") of one postingaccount, holding its postings of the requested period.
The postingaccount numbers available for a sums report are provided by reports/get/sums, both as the keys of the 'sums' object and as its entries' 'postingaccount_number'.
In contrast to the report itself the ledger is created on the fly, so no report has to be created beforehand. Note that retrieving the ledger of a postingaccount holding a lot of postings may take a while.
Use to read one posting account's ledger for a bounded date range.
For the totals across all posting accounts, use reports_get_sums.
The API returns the ledger on demand; no previously generated sums report or report ID is required.
Endpoint: POST /reports/get/sums/ledger
Inputs: date_to (required), date_from (required), postingaccount_number (required), base. Returns: message, success, report_sums_postingaccount_ledger
transactions_assign_receiptsTransactions: assign receipt to transactionA
🟡 WRITE · links/unlinks records: Creates or removes an assignment between records (e.g. receipt ↔ transaction). Reversible.
assign receipt to transaction
Assign a receipt to a transaction.
Use to match receipts to the bank transactions that paid them, one pair or many at once.
To attach a receipt to a posting rather than a bank transaction, use postings_assign_receipt_to_free.
Takes one or many: pass an array of transactions to receipts in transactions_to_receipts. A single record is an array of one.
Reversible with transactions_unassign_receipt. Creating the link does not book anything: use postings_create_for_transaction to post the transaction.
Endpoint: POST /transactions/assign-batch/receipt
Inputs: transactions_to_receipts (required). Returns: errors, success, transactions_to_receipts
transactions_createTransactions: add transactionA
🟡 WRITE · creates data: Creates new records (receipts, transactions, postings, invoices, master data). Not idempotent: calling twice may create duplicates.
add transaction
Add a transaction to a payment account of the specified customer.
Use to import bank transactions that no bank connection delivers automatically, for example from a CSV export or a cash book.
Takes one or many: pass an array of transactions in transactions. A single record is an array of one.
Not idempotent and there is no duplicate detection: re-importing the same statement books every line a second time. Check transactions_list for the date range first. v1 offers no endpoint to update or delete an imported transaction.
Endpoint: POST /transactions/addBatch
Inputs: transactions (required). Returns: errors, success, transactions
transactions_get_by_idTransactions: get transaction by id_by_customerARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get transaction by id_by_customer
Get a single transaction for a specified customer account by id_by_customer. You can get the "id_by_customer" by using the "/transactions/get method" first. The response includes an array of transaction data.
Use to fetch a single bank transaction whose id you already have.
To search or page through transactions, use transactions_list.
id_by_customer is the per-customer counter shown in the BuchhaltungsButler UI, not a global database id.
Endpoint: POST /transactions/get/id_by_customer
Inputs: id_by_customer (required). Returns: data, message, success
transactions_listTransactions: get transactionsARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get transactions
Get transactions for a specified customer account. The response includes the number of returned rows and an array of transaction datas.
Use to search bank transactions by account and date range.
To fetch one known transaction, use transactions_get_by_id.
For multi-page exports, prefer id_by_customer_from with limit and fixed account/date filters: it is exclusive and forces ID-ascending order. Start at 0, then use the greatest returned ID without incrementing it; omit offset. Validate IDs and forward progress and continue until empty. Offset pages have overlapped in observed filtered exports; deduplication and an empty final page do not prove completeness. Reconcile IDs/counts and signed amounts independently. rows counts the returned page, not the grand total; concurrent changes still need a separate check.
Endpoint: POST /transactions/get
Inputs: limit, offset, account, date_to, +5 more. Returns: data, rows, message, success
transactions_list_assigned_receiptsTransactions: get all receipts assigned to a specific transactionARead-onlyIdempotent
🟢 READ-ONLY: Fetches data. Makes no changes to the accounting records.
get all receipts assigned to a specific transaction
Get all receipts assigned to a specific transaction for a specified customer account by id_by_customer. You can get the "id_by_customer" by using the "/transactions/get method" first.
Use to see which receipts are linked to a given bank transaction, for example to check whether a payment has its invoice attached.
For the opposite direction, use receipts_list_assigned_transactions.
Endpoint: POST /transactions/assigned-receipts/get
Inputs: transaction_id_by_customer (required), confirmed_only. Returns: data, rows, message, success
transactions_unassign_receiptTransactions: unassign a specific receipt from a transactionA
🟡 WRITE · links/unlinks records: Creates or removes an assignment between records (e.g. receipt ↔ transaction). Reversible.
unassign a specific receipt from a transaction
Unassign a specific receipt from a transaction.
Use to undo a receipt-to-transaction match that was made in error.
Removes only the link. Neither the receipt nor the transaction is deleted.
Endpoint: POST /transactions/unassign/receipt
Inputs: receipt_id_by_customer (required), transaction_id_by_customer (required). Returns: message, success
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 46 tools
Tools are largely differentiated by resource and action, and descriptions explicitly distinguish easily confused pairs such as accounts vs postingaccounts, debtors vs creditors, and receipt/transaction/free postings. The main remaining risk is cognitive load from many near-parallel variants like postings_create_for_transaction, postings_create_for_receipt, and postings_create_free, which require description reading to choose correctly.
Names consistently follow an entity_action snake_case convention: debtors_create, receipts_list, postings_unconfirm_for_receipt, reports_get_sums_ledger, etc. Although the pattern is noun-first rather than verb-first, it is applied predictably across the entire set.
With 46 tools, the surface is very heavy for agent selection and exceeds the practical range for reliable tool choice. The breadth reflects a substantial accounting domain, but the many analogous create/unconfirm/assign variants make the set cumbersome.
Coverage is broad across master data, receipts, transactions, postings, and reports, with useful cross-references and workaround guidance. However, lifecycle gaps are notable: invoices cannot be listed or retrieved after creation, transactions lack update/delete, several master-data resources lack delete, and comments are write-only.
Maintenance
Related MCP Connectors
Malaysian SME accounting, e-Invoice and payroll for your AI. 77 tools; writes are approved drafts.
DATEV financial data for AI assistants: P&L, KPIs, bookings, budgets and monthly reporting.
Query your books, company data, business health, and ship invoices from your AI assistant.
Connect ChatGPT and Claude to Fortnox: invoices, customers, reports. Every write needs your OK.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to interact with QuickFile UK accounting software, providing access to invoicing, client management, purchases, banking, and financial reporting through 40+ tools covering the complete QuickFile API.22 npm4MIT
- AlicenseNot gradedqualityDmaintenanceIntegrates with the sevdesk German accounting API, providing 76 tools for full CRUD operations across contacts, invoices, vouchers, orders, credit notes, bank accounts, transactions, parts, tags, addresses, and communication ways.178 npm6MIT
- AlicenseCqualityCmaintenanceProvides comprehensive AI-agnostic access to all Firefly III personal finance features via 66 tools, enabling natural language management of accounts, transactions, budgets, and more.667 npm24MIT
- AlicenseBqualityDmaintenanceEnables AI assistants to interact with the BuchhaltungsButler accounting API via MCP, providing tools for managing receipts, transactions, invoices, postings, and master data directly from Claude Desktop and other MCP-compatible clients.2320 npmMIT