Blog / development

Beleg ins Chatfenster, Fall erledigt: wie wir unsere Buchhaltung an die Claude-App angeschlossen haben – mit genau einer Bestätigung

Beleg-PDF in den Chat, Claude findet die Zahlung, ein Klick schließt den Fall. Wie wir einem Sprachmodell Schreibrechte geben, ohne die Kontrolle abzugeben.

Symbolbild: Ein Messingschlüssel steckt in einem verzierten Schloss an einer dunkelgrünen Tür, ein zweites Schlossschild liegt abgenommen auf dem Boden

Ein Beleg, fünf Handgriffe

Unsere eigene Buchhaltung, accounting.ext.dev, entwickeln wir selbst. Sie gleicht Bankumsätze mit Rechnungen ab, und wo sie sich nicht sicher ist, legt sie einen Prüffall an: eine Zahlung, zu der ein Beleg fehlt oder nicht eindeutig passt.

Am 18. Oktober 2026 waren das rund 30 Belege. Für jeden waren fünf Handgriffe außerhalb der Anwendung nötig: das PDF ins Dokumentenarchiv hochladen, dort Lieferant, Dokumenttyp und Schlagworte setzen, den Import anstoßen, den Rechnungsentwurf vervollständigen und schließlich den Prüffall entscheiden.

Das Ziel: das PDF in den Chat der Claude-App ziehen, Claude findet die passende Zahlung, zeigt, was passieren würde – und ein Klick schließt den Fall. Möglich macht das ein MCP-Server, eine Schnittstelle nach dem Model Context Protocol, über die ein KI-Assistent die Daten und Handgriffe einer Anwendung nutzen kann. Was das ist und wofür es sich eignet, beschreiben wir auf unserer Seite zu MCP-Servern.

Die Herausforderung

„KI kann Buchhaltung“ ist nicht die spannende Frage. Spannend ist, wie man einem Sprachmodell Schreibrechte auf echte Geschäftsdaten gibt, ohne die Kontrolle abzugeben:

  • Wer darf was? Die Claude-App braucht eine Anmeldung an der Buchhaltung, die sich widerrufen lässt und nicht mehr erlaubt als nötig.
  • Fremde Texte sind gefährlich. Verwendungszwecke, Namen von Zahlern und Rechnungstexte stammen von Dritten. Wer seinen Kontonamen auf „Ignoriere alle bisherigen Anweisungen und …“ setzt, darf damit das Modell nicht steuern.
  • Ein Klick muss reichen – aber nicht blind. Wer bestätigt, muss vorher lesbar sehen, was geschrieben wird. Eine festgeschriebene Rechnung lässt sich nicht mehr ändern.
  • MCP kann keine Dateien übergeben. Die Werkzeuge eines MCP-Servers bekommen ihre Argumente als JSON. Das PDF, das im Chat liegt, sieht das Modell als Inhalt, nicht als Datei.

Unsere Lösung

1. Anmeldung über den bestehenden Login, getrennte Rechte

Der MCP-Server läuft in der Buchhaltung selbst und nutzt deren Geschäftslogik – es gibt keine zweite. Die Claude-App meldet sich nach OAuth 2.1 mit PKCE an: Die Anmeldung läuft über den Login, den die Anwendung ohnehin hat, danach entscheidet die Person auf einer Freigabeseite, was die Verbindung darf.

Es gibt genau zwei Rechte: Lesen und Prüfen. Ein Administrator-Recht gibt es über den Chat bewusst nicht, auch wenn die Person in der Anwendung selbst Administrator ist. Jede Verbindung steht in den Einstellungen der Anwendung und lässt sich einzeln widerrufen, jeder Aufruf wird protokolliert, und ein Schalter legt den gesamten Zugang auf einen Schlag still.

2. Belegtexte sind Daten, keine Anweisungen

Alles, was von Dritten stammt, erreicht das Modell nur in einem eigenen, gekennzeichneten Feld (untrusted_text), gekürzt und mit dem Hinweis, dass es sich um Daten handelt. In der Prüfung vor der Freigabe fiel auf, dass das nicht reichte: Die Abgleichslogik zitiert in ihren Begründungen den Namen des Zahlers wörtlich – und diese Begründungen standen außerhalb des geschützten Felds. Seitdem gilt die Regel auch für Begründungen und für Rechnungsnummern von Lieferanten, und ein Test prüft, dass ein solcher Name an keiner anderen Stelle der Antwort auftaucht.

3. Erst die Vorschau, dann die Bestätigung

Kein Werkzeug schreibt beim ersten Aufruf. Es läuft zunächst als Trockenübung durch denselben Code wie der echte Vorgang, der am Ende alles wieder zurücknimmt, und liefert eine lesbare Vorschau: „Rechnung … vom 30.01., 157,80 € → Lastschrift vom 03.02., Fall wird geschlossen“. Dazu kommt eine Einmal-ID:

  • Sie gilt nur für diese Verbindung, dieses Werkzeug und genau diese Argumente.
  • Sie ist an den Stand des Falls gebunden: Hat sich der Fall inzwischen geändert, wird nichts geschrieben.
  • Sie verfällt nach zehn Minuten und lässt sich nur einmal einlösen.

Bestätigt wird ausschließlich mit dieser ID. Was geschrieben wird, liegt auf dem Server; das Modell kann zwischen Vorschau und Bestätigung nichts mehr austauschen.

Weil MCP keine Dateien an ein Werkzeug übergeben kann, gibt ein Werkzeug einen kurzlebigen Upload-Link heraus: gültig 15 Minuten, für genau eine Datei, an die Verbindung und auf Wunsch an den Prüffall gebunden. Der Link selbst ist die Berechtigung, eine Anmeldung ist nicht nötig.

Zuerst war der Link für die Person gedacht. Dann zeigte sich, dass es auch ohne geht: In der Claude-App liegen angehängte Dateien als echte Dateien in der Umgebung, in der Claude Code ausführen kann. Ist der Netzzugriff auf die Buchhaltung dort freigegeben, lädt Claude den Beleg selbst hoch. Nur wenn das nicht geht, bekommt die Person den Link.

Die Buchhaltung legt den Beleg im Dokumentenarchiv ab, mit Typ, Schlagworten und Lieferant. Liegt dieselbe Datei dort schon, wird keine zweite Kopie angelegt. Dann folgt derselbe Import wie im nächtlichen Lauf. Die Werte, die Claude aus dem PDF gelesen hat – Nummer, Datum, Beträge –, prüft der Server gegen den Text der Texterkennung, bevor er sie übernimmt.

5. Der Beleg ohne ein Wort dazu

Damit niemand „ordne das bitte zu“ tippen muss, bringt der Server eine kurze Anweisung mit, die in jedem Chat mit der Buchhaltung gilt: Sieht ein geteiltes Dokument aus wie eine Rechnung, ein Beleg oder eine Gutschrift, liest Claude Lieferant, Nummer, Datum und Betrag, sucht den passenden Prüffall und schlägt ihn vor. Diese Suche schreibt nichts; die gelesenen Werte sind nur Suchhinweise. Passt genau ein Fall gut, schlägt Claude ihn direkt vor, bei mehreren fragt es nach, bei keinem bietet es an, den Beleg ohne Fall abzulegen.

Der erste Echtbetrieb: zwei Bestätigungen sind eine zu viel

Alle Tests waren grün. Der echte Betrieb deckte trotzdem auf, was Tests nicht abbilden.

Schon die Verbindung scheiterte zunächst an der Freigabeseite: Wegen einer Sicherheitseinstellung des Webservers schickte der Browser beim Absenden keine Herkunft mit, also wies die Anwendung das Formular als fremde Anfrage zurück. Die Tests hatten nie eine Herkunft mitgeschickt und es deshalb nicht bemerkt. Danach bekam die Verbindung nur das Recht zum Lesen, weil die Claude-App von sich aus kein weiteres anfordert. Seitdem bietet die Freigabeseite „Prüfen“ zum Ankreuzen an.

Der lehrreichste Fund kam beim ersten echten Beleg in der Nacht zum 19. Oktober. Claude fand den Fall und lud die Datei selbst hoch – so weit wie geplant. Für den Abschluss waren aber zwei Schritte nötig: erst den Rechnungsentwurf festschreiben, dann der Zahlung zuordnen. Das Modell bereitete beide auf einmal vor. Die erste Vorschau wurde nie bestätigt, die zweite scheiterte, weil der Beleg noch ein Entwurf war. Der Fall blieb offen, während wir ihn für erledigt hielten.

Zwei Bestätigungen hintereinander klingen nach doppelter Sicherheit. In der Praxis sind sie eine Gelegenheit mehr, dass etwas auf halbem Weg liegen bleibt.

Die Lösung war, den Ablauf zu vereinfachen statt die Anweisungen zu verlängern:

  1. Ein Werkzeug übernimmt Festschreiben und Zuordnen zusammen.
  2. Eine Vorschau zeigt beides: welche Rechnung mit welchen Beträgen, zu welcher Zahlung, und dass der Fall danach geschlossen ist.
  3. Eine Bestätigung schreibt alles in einer einzigen Transaktion. Scheitert ein Teil, wird gar nichts geschrieben.
  4. Erfolg erst nach dem Schreiben: Claude darf einen Fall erst als erledigt melden, wenn die Bestätigung tatsächlich geschrieben hat. Ist eine Vorschau verfallen, sagt es das und bietet sie neu an – auch in einem späteren Chat.

Bei dieser Gelegenheit prüft das Werkzeug jetzt jeden Wert, den es schreibt, gegen den Import oder den Belegtext, und dazu den Lieferanten: Nennt das Modell einen Lieferanten, muss die Zahlung zu ihm passen oder der Beleg ihn nennen, mit Name oder Umsatzsteuer-ID. Ändert sich der Lieferant gegenüber dem Import, steht das ausdrücklich in der Vorschau.

Nebenbefunde

Die 30 Belege vom 18. Oktober brachten noch etwas ans Licht. Zwölf davon waren Rechnungen von US-Softwareanbietern in Dollar, bezahlt per Karte in Euro. Die Buchhaltung ordnete keine davon zu, weil der Euro-Betrag nie genau zum Dollar-Betrag passt. Jetzt rechnet sie mit dem Referenzkurs der EZB am Rechnungs- und am Buchungstag, lässt den Aufschlag der Kartengesellschaft zu und erwartet die Belastung bis zu fünf Tage nach dem Rechnungsdatum. Ein Probelauf über alle betroffenen Euro-Zahlungen auf den echten Daten ordnete 38 statt 32 automatisch zu, ohne eine einzige falsche Zuordnung.

  • 32 → 38 automatische Zuordnungen im Probelauf
  • 0 falsche Zuordnungen
  • 2 Zahlungen bleiben bewusst bei einem Menschen

Die zwei bleiben offen, weil sich ihre Rechnungen um sieben Cent unterscheiden und wenige Tage auseinanderliegen. Keine feste Regel kann sie sicher trennen. Lieber einmal fragen als einmal falsch zuordnen.

Das Ergebnis

  • Beleg in den Chat, eine Bestätigung, Fall geschlossen – Hochladen, Ablegen, Import, Festschreiben und Zuordnen ohne Handgriff außerhalb des Chats.
  • Zwei Rechte, kein Administrator: Lesen und Prüfen, jede Verbindung einzeln widerrufbar, jeder Aufruf im Protokoll.
  • Nichts wird ungesehen geschrieben: Jede Änderung hat eine Vorschau und eine Einmal-ID, die nach zehn Minuten verfällt.
  • Fremde Texte bleiben Daten: Was auf einem Beleg oder in einem Verwendungszweck steht, kann das Modell nicht steuern.
  • Werte mit Beleg: Nummer, Datum, Beträge und Lieferant werden gegen den Import oder den Belegtext geprüft.

Die Buchhaltung, um die es hier geht, ist unsere eigene; produktiv einsetzen werden wir sie ab 2027. Kontoumsätze bekommt sie übrigens von unserem Open-Source-Werkzeug fints2camt.

Fazit

Einem Sprachmodell Schreibrechte zu geben, ist vor allem eine Frage der Gestaltung: wenige Rechte, fremde Texte als Daten, eine lesbare Vorschau und eine Bestätigung, die genau das schreibt, was gezeigt wurde. Und der Echtbetrieb lehrt, was kein Test zeigt – hier, dass eine Bestätigung sicherer ist als zwei.

Ihr Team soll mit einem KI-Assistenten in Ihre eigene Anwendung schreiben dürfen?

Wir schauen uns gemeinsam mit Ihnen an, welche Handgriffe sich dafür eignen und wie Vorschau, Rechte und Protokoll dafür aussehen müssen.

Projekt besprechen
Christopher Zechendorf
Christopher Zechendorf Christopher Zechendorf leitet die ext.dev GmbH und bringt über 25 Jahre Erfahrung in Webentwicklung, CMS-Systemen und Infrastruktur mit.