ohneben's Buchhaltungsbutler MCP

Verwalte deine BuchhaltungsButler-Buchhaltung in natürlicher Sprache aus KI-Assistenten wie Claude, Cursor und jedem anderen MCP-Client.

Documentation

ohneben's Buchhaltungsbutler MCP

Buy Me A Coffee

CI Image & MCP-Registry veröffentlichen Lizenz: MIT Buchhaltungsbutler-MCP MCP server

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, automatisch aus der offiziellen OpenAPI-Spezifikation (Spec-Version 1.9.1) als MCP-Tools 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 bekommstWarum das zählt
Alle 54 Endpunkte, automatisch generiert aus der offiziellen SpecVollstä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 (readOnlyHint, destructiveHint)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 HTTPLokal in Claude Desktop nutzen — oder einen dauerhaft laufenden Server betreiben, den beliebig viele MCP-Clients über HTTP erreichen.
Docker + docker-compose, Health-Check, Auto-RestartProduktionsnahes Deployment ab Werk: docker compose up, und er bleibt oben.
Optionale Bearer-Token-Authentifizierung am HTTP-EndpunktSichere den Server mit einem gemeinsamen Geheimnis ab, sobald er über localhost hinaus erreichbar ist.
Eingebautes Rate-LimitingDrosselt sich selbst unter dem BuchhaltungsButler-Limit von 100 Anfragen/Kunde/Minute, damit du nie dagegenläufst.
Deine Zugangsdaten erreichen das Modell nieDie 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ähigkeitDieses ProjektGenerischer OpenAPI→MCP-Wrapper*
Alle 54 BuchhaltungsButler-Endpunkte als Tools
🟢 / 🟡 / 🔴 Sicherheitskategorie + Banner pro Tool
readOnlyHint / destructiveHint MCP-Annotationen
$ref-Auflösung für Batch-Payloads + HTML-bereinigte Beschreibungen
Eingebautes Rate-Limiting (bleibt unter BBs 100/Kunde/Min.)
stdio-Transport
Streamable-HTTP-Transport
Docker + docker-compose, Health-Check, Auto-Restart
Optionale Bearer-Token-Auth am Endpunkt
Credentials serverseitig injiziert, nie ans Modell gesendet
LizenzMITunterschiedlich

*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.

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 auf eine lange Zufallszeichenkette setzen,
#                   falls der Server über localhost hinaus erreichbar ist

2. Server starten:

docker compose up -d --build

3. 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, wenn du MCP_AUTH_TOKEN leer gelassen hast.)

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:latest

API-Zugangsdaten besorgen

BuchhaltungsButler nutzt zwei Authentifizierungsebenen (siehe die offizielle Dokumentation):

  1. HTTP-Basic-Auth — ein API Client + API Secret, deine globalen API-Zugangsdaten. Zu finden bzw. anzulegen in BuchhaltungsButler unter Einstellungen → API.
  2. 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):

VariablePflichtStandardBeschreibung
BB_API_CLIENTAPI Client (Basic-Auth-Benutzername)
BB_API_SECRETAPI Secret (Basic-Auth-Passwort)
BB_API_KEYStandard-Kunden-api_key
MCP_TRANSPORTstdiostdio oder http (das Docker-Image nutzt standardmäßig http)
PORT3000HTTP-Port, auf dem gelauscht wird
HOST0.0.0.0HTTP-Bind-Adresse
MCP_HTTP_PATH/mcpHTTP-Route für MCP
MCP_AUTH_TOKEN(aus)Verlangt Authorization: Bearer <Token> auf /mcp
BB_RATE_LIMIT90Clientseitiges Limit an Anfragen pro Minute
BB_BASE_URL(aus der Spec)Überschreibt die Basis-URL der API

Nach Änderungen an .env neu laden mit docker compose up -d --force-recreate.

Sicherheitskategorien der Tools

Jede Tool-Beschreibung beginnt mit einem dieser Banner und trägt die passenden MCP-Annotationen:

BannerAnzahlreadOnlyHintdestructiveHintBedeutung
🟢 READ-ONLY15truefalseRuft nur Daten ab. Ungefährlich.
🟡 WRITE · legt Daten an24falsefalseErzeugt Datensätze (nicht idempotent — mehrfach aufgerufen entstehen Duplikate).
🟡 WRITE · ändert Daten4falsefalseÄndert bestehende Stammdaten direkt.
🟡 WRITE · verknüpft/löst4falsefalseOrdnet Beleg ↔ Transaktion zu bzw. hebt die Zuordnung auf. Umkehrbar.
🟡 WRITE · nimmt Zustand zurück4falsefalseSetzt Buchungen auf unbestätigt / stellt Belege wieder her. Umkehrbar.
🔴 DESTRUCTIVE · löscht3falsetrueLö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.

Mit npm run list-tools (ohne Zugangsdaten) lässt sich der vollständige Katalog jederzeit ausgeben.

🟢 READ-ONLY (15)
ToolEndpunkt
accounts_getPOST /accounts/get
cost_locations_getPOST /cost-locations/get
postings_getPOST /postings/get
receipts_getPOST /receipts/get
receipts_get_id_by_customerPOST /receipts/get/id_by_customer
receipts_assigned_transactions_getPOST /receipts/assigned-transactions/get
reports_get_bwaPOST /reports/get/bwa
reports_get_sumsPOST /reports/get/sums
reports_get_sums_ledgerPOST /reports/get/sums/ledger
transactions_getPOST /transactions/get
transactions_get_id_by_customerPOST /transactions/get/id_by_customer
transactions_assigned_receipts_getPOST /transactions/assigned-receipts/get
settings_get_creditorsPOST /settings/get/creditors
settings_get_debtorsPOST /settings/get/debtors
settings_get_postingaccountsPOST /settings/get/postingaccounts
🟡 WRITE · legt Daten an (24)
ToolEndpunkt
accounts_addPOST /accounts/add
comments_addPOST /comments/add
cost_locations_addPOST /cost-locations/add
invoices_createPOST /invoices/create
invoices_create_draftPOST /invoices/create/draft
invoices_create_e_invoicePOST /invoices/create/e-invoice
postings_add_freePOST /postings/add/free
postings_add_receiptPOST /postings/add/receipt
postings_add_transactionPOST /postings/add/transaction
postings_add_batch_freePOST /postings/add-batch/free
postings_add_batch_receiptsPOST /postings/add-batch/receipts
postings_add_batch_transactionsPOST /postings/add-batch/transactions
receipts_addPOST /receipts/add
receipts_addBatchPOST /receipts/addBatch
receipts_uploadPOST /receipts/upload
reports_create_bwaPOST /reports/create/bwa
reports_create_sumsPOST /reports/create/sums
settings_add_creditorPOST /settings/add/creditor
settings_add_debtorPOST /settings/add/debtor
settings_add_postingaccountPOST /settings/add/postingaccount
settings_add_batch_creditorsPOST /settings/add-batch/creditors
settings_add_batch_debtorsPOST /settings/add-batch/debtors
transactions_addPOST /transactions/add
transactions_addBatchPOST /transactions/addBatch
🟡 WRITE · ändert (4) · verknüpft (4) · nimmt zurück (4)
ToolEndpunktUnterkategorie
cost_locations_updatePOST /cost-locations/updateändert
settings_update_creditorPOST /settings/update/creditorändert
settings_update_debtorPOST /settings/update/debtorändert
settings_update_postingaccountPOST /settings/update/postingaccountändert
transactions_assign_receiptPOST /transactions/assign/receiptverknüpft
transactions_assign_batch_receiptPOST /transactions/assign-batch/receiptverknüpft
transactions_unassign_receiptPOST /transactions/unassign/receiptverknüpft
postings_assign_receipt_to_free_postingPOST /postings/assign/receipt-to-free-postingverknüpft
postings_unconfirm_freePOST /postings/unconfirm/freenimmt zurück
postings_unconfirm_receiptPOST /postings/unconfirm/receiptnimmt zurück
postings_unconfirm_transactionPOST /postings/unconfirm/transactionnimmt zurück
receipts_restore_id_by_customerPOST /receipts/restore/id_by_customernimmt zurück
🔴 DESTRUCTIVE · löscht (3)
ToolEndpunktHinweis
receipts_delete_id_by_customerPOST /receipts/delete/id_by_customerWiederherstellbar über receipts_restore_id_by_customer
cost_locations_deletePOST /cost-locations/deleteNicht wiederherstellbar
postings_cancelPOST /postings/cancelNoch nicht festgeschriebene Buchungen werden gelöscht; festgeschriebene werden durch eine Stornobuchung ausgeglichen

Aus dem Quellcode starten (stdio, ohne Docker)

Du bevorzugst den klassischen stdio-Modus für Claude Desktop? Dann lokal bauen:

npm install
npm run build

Anschließ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 build

Neue 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.version in 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

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.

Hinweise & Konventionen

  • Datumsangaben: YYYY-MM-DD. Beträge: Punkt als Dezimaltrennzeichen (z. B. -12.30).
  • Datei-Uploads (receipts_upload, receipts_add, receipts_addBatch): Die Datei wird als Base64-Zeichenkette im Feld file übergeben.
  • Blättern: Die meisten get-Tools akzeptieren limit und offset.
  • Batch-Tools erwarten Arrays von Objekten; die Item-Schemata werden aus den Spec-Definitionen aufgelöst und dem Modell mitgegeben.
  • Auswertungen (BWA, Summen- und Saldenliste) werden asynchron im Hintergrund erzeugt: erst reports_create_* aufrufen, dann reports_get_* mit der zurückgegebenen id_by_customer. Eine neue Auswertung desselben Typs ersetzt die vorherige.
  • 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 ist standardmäßig nicht authentifiziert (auf localhost unbedenklich). Um ihn über deinen Rechner hinaus verfügbar zu machen, setze MCP_AUTH_TOKEN und sende ihn als Authorization: Bearer <Token>-Header — idealerweise hinter TLS.

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.