Zum Hauptinhalt springen
Der Fynn MCP-Server setzt das Model Context Protocol um und macht die wichtigsten Fynn-Funktionen für KI-Assistenten wie Claude direkt zugänglich. Statt eine Benutzeroberfläche zu öffnen, beschreibst du, was du brauchst, und der Assistent ruft die passenden Tools auf. Typische Einsatzfälle:
  • Kunden- und Rechnungsdaten per Sprache abfragen
  • Angebote automatisiert befüllen, inklusive Preisrecherche und Bildern
  • DATEV-Cloud-Export per Bestätigungsdialog starten

Verbindung einrichten

Endpunkt

Für die Sandbox-Umgebung ersetze den Host durch preview.coreapi.io.

Transport

Der Server verwendet Streamable HTTP (MCP-Spezifikation 2025-03-26). MCP-Clients, die dieses Transport-Protokoll unterstützen, verbinden sich direkt mit dem Endpunkt oben.

Authentifizierung

Jede Anfrage benötigt zwei Header: Den API-Schlüssel erstellst du unter Einstellungen > API-Schlüssel. Die Organisations-ID findest du in den Einstellungen deiner Organisation.

Konfigurationsbeispiel

Die meisten MCP-Clients (z. B. Claude Desktop) nehmen eine JSON-Konfiguration. Hier ein Beispiel:

Berechtigungen

Alle Tools respektieren die Rollen-Berechtigungen des verbundenen Nutzers. Wer in Fynn keine Rechnung lesen darf, bekommt über den MCP-Server auch keine. Die Anfrage schlägt in dem Fall mit einer klaren Fehlermeldung fehl, statt leere Daten zu liefern.

Tool-Referenz

Die folgenden 31 Tools stehen zur Verfügung, gruppiert nach Funktionsbereich.

Allgemein

fynn_ping

Prüft die Verbindung, Authentifizierung und den Organisations-Kontext. Gibt ok, die Organisations-ID und einen Zeitstempel zurück. Nimmt keine Parameter entgegen.

Kunden

Sucht nach Kunden anhand eines Suchbegriffs oder einer Abonummer. Gibt Identitätsfelder zurück (ID, Kundennummer, Anzeigename, Typ, Status), keine Adressen oder Kontaktdaten.

customer_balance

Liefert den Debitorensaldo eines Kunden. Ohne Zeitraum den aktuellen Gesamtsaldo, mit Zeitraum zusätzlich Soll-/Haben-Summen. Beträge sind in Cent mit Währungsangabe.

customer_payments

Listet Zahlungstransaktionen eines Kunden, neueste zuerst. Enthält Datum, Betrag (Cent), Status, Zahlungsart und Belegnummer, jedoch keine Bankdaten oder IBAN.

Rechnungen

Sucht Belege (Rechnungen, Gutschriften, Stornos). Filterbar nach Status, Belegtyp, Kunde und Finalisierungszeitraum. Beträge in Cent, Daten als ISO-8601.

invoice_reference_chain

Löst die Storno-/Referenzkette eines Belegs auf. Gibt den Beleg selbst, den referenzierten Ursprungsbeleg sowie alle Stornos/Gutschriften zurück, die auf diesen Beleg verweisen.

invoice_pdf_download

Erstellt einen zeitlich begrenzten Download-Link für die PDF-Datei eines Belegs. Gibt url, filename und expiresAt zurück, keine Binärdaten.

invoices_zip_download

Bündelt die PDFs mehrerer Belege in ein ZIP-Archiv und gibt einen signierten Download-Link zurück. Belege ohne PDF werden übersprungen.

Rechnungen erstellen und bearbeiten

Die schreibenden Rechnungs-Tools erfordern die Berechtigung invoice:write. Eine Rechnung durchläuft dabei einen klaren Lebenszyklus: Anlegen als Entwurf, Positionen hinzufügen und bearbeiten, und schließlich Finalisieren oder Schließen. Eine finalisierte Rechnung ist unveränderlich und rechtlich bindend; für die Finalisierung ist daher eine manuelle Freigabe durch einen Menschen erforderlich.

invoice_create

Legt eine neue Rechnung im Status Entwurf an. Positionen werden nicht hier, sondern anschließend mit invoice_add_position oder invoice_add_product_position hinzugefügt. Gibt die neue Entwurfs-Rechnung mit Kopfdaten, Positionen und Summen (in Cent) zurück.

invoice_get

Liest eine Rechnung mit Kopfdaten, Positionen und Summen. Die Rechnungs-ID kann eine UUID oder eine Belegnummer sein. Gibt zurück: Kopfdaten (id, number, status, type, customer, currencyCode, dueDate, finalizedAt, title, introduction, closing, internalNote), Summen (totals.net/tax/gross in Cent), Positionen und ein editable-Kennzeichen.

invoice_update

Aktualisiert die Kopf-Felder einer noch nicht finalisierten Rechnung. Nur mitgesendete Felder werden geändert; fehlende Felder bleiben unverändert. Gibt die aktualisierte Rechnung zurück (gleiche Struktur wie invoice_get).

invoice_add_position

Fügt einer Entwurfs-Rechnung eine frei definierte Position hinzu. Preis und Steuergruppe sind immer explizit anzugeben. Gibt { positionId, invoice } zurück, wobei invoice die aktualisierte Rechnung mit Summen in Cent enthält.

invoice_add_product_position

Leitet eine Rechnungsposition aus einem Produkt im Katalog ab. Bezeichnung, Einheit und Steuergruppe stammen aus dem Produkt; der Preis kommt entweder aus einem Flat-Fee-Preisplan oder aus einem expliziten Preis-Override.
Ein Preis wird nie geraten. Fehlt sowohl ein passender Preisplan als auch ein unitPrice-Override, lehnt das Tool die Anfrage mit einer klaren Fehlermeldung ab.
Gibt { positionId, invoice } zurück (Summen in Cent).

invoice_update_position

Aktualisiert eine Position einer bearbeitbaren Rechnung. Nur mitgesendete Felder werden geändert. Gibt { positions[], totals } zurück (Beträge in Cent).

invoice_remove_position

Entfernt eine Position von einer bearbeitbaren Rechnung. Die verbleibenden Positionen werden neu nummeriert und die Summen neu berechnet. Gibt { positions[], totals } zurück (Beträge in Cent).

invoice_close

Schließt eine Rechnung endgültig, ohne sie zu finalisieren. Der Beleg erhält den Status STATUS_CLOSED und wird verworfen: keine Belegnummer, kein PDF, keine Zahlung. Nur aus den Status Entwurf (STATUS_DRAFT) oder STATUS_NEW heraus möglich. Gibt { id, status } zurück.

invoice_finalize

Bereitet die Finalisierung einer Rechnung vor und legt eine Freigabe-Aufgabe in der App-Inbox an. Die Rechnung wird dabei nicht direkt finalisiert. Da eine finalisierte Rechnung rechtlich bindend und unveränderlich ist, läuft die Finalisierung zweistufig ab: Der KI-Assistent prüft, ob die Rechnung finalisierbar ist (gültige Zahlungsart, aktiver Kunde), und legt dann eine Freigabe-Aufgabe an. Ein Mensch prüft und genehmigt diese anschließend in der App-Inbox. Erst nach der manuellen Freigabe wird die Rechnung tatsächlich finalisiert. Ein zweiter Aufruf für dieselbe Rechnung liefert die bereits vorhandene offene Aufgabe zurück, sofern die Rechnung seit der ersten Anfrage nicht verändert wurde; die Parameter der ursprünglichen Anfrage bleiben dabei bestehen. Wurde die Rechnung geändert, wird die alte Aufgabe verworfen und eine neue mit neuer actionItemId angelegt. Freigabe-Anfragen verfallen 72 Stunden nach der Erstellung und müssen dann erneut gestellt werden. Gibt { actionItemId, status: "pending_approval", invoiceId, summary, hint } zurück, wobei summary Gesamtbeträge (Netto, Steuer, Brutto in Cent), Anzahl Positionen und Kundendaten enthält, und hint den Hinweis auf die notwendige manuelle Freigabe in der Inbox. Mit pending_action_status (Parameter actionItemId) kannst du den Freigabestatus und das Ablaufdatum abfragen. Berechtigung: invoice:finalize.

pending_action_status

Fragt den Status einer Freigabe-Aufgabe ab, zum Beispiel einer per invoice_finalize angelegten Rechnungsfreigabe. Gibt { id, type, status, createdAt, resolvedAt, expiresAt, invoiceId, executions } zurück. expiresAt ist der Zeitpunkt (UTC), zu dem die Freigabe-Anfrage abläuft; danach muss sie per invoice_finalize neu angefordert werden. Mögliche Werte für status: open, snoozed, in_progress, resolved, dismissed. Jeder Eintrag in executions enthält actionKey (z. B. approve oder reject), resultStatus (success oder failure), resultMessage und executedAt. Bei erfolgreicher Freigabe steht in resultMessage die vergebene Belegnummer. Schlägt die Freigabe fehl, weil die Rechnung nach der Anfrage geändert wurde oder die Anfrage abgelaufen ist, enthält resultMessage den Grund; die Rechnung bleibt in dem Fall unfinalisiert. Berechtigung: action-item:read.

Rechnung mit KI erstellen und finalisieren: ein typischer Ablauf

So erstellst du mit einem KI-Assistenten eine vollständige Rechnung und sendest sie zur Freigabe:
1

Rechnung anlegen

Lege eine neue Rechnung für den gewünschten Kunden an:
Die Antwort enthält die invoiceId, die du für alle weiteren Aufrufe benötigst.
2

Positionen hinzufügen

Füge Positionen aus dem Katalog oder frei definierte Positionen hinzu:
Beachte: unitPrice kommt immer aus dem Preisplan oder einem expliziten Override, nie aus einer Schätzung.
3

Rechnung prüfen

Lies die aktuelle Rechnung mit allen Positionen und Summen, bevor du die Finalisierung anforderst:
4

Freigabe anfordern

Erstelle die Freigabe-Aufgabe. Die Rechnung wird noch nicht finalisiert:
Die Antwort enthält actionItemId, status: "pending_approval", eine Zusammenfassung der Rechnung und einen hint-Text. Informiere die Nutzerin oder den Nutzer, dass die Freigabe in der App-Inbox wartet.
5

Mensch prüft und gibt frei

Ein Mitarbeiter öffnet die Inbox, prüft die Rechnung und gibt sie frei oder lehnt sie ab. Dieser Schritt findet ausschließlich in der App statt und kann nicht durch den KI-Assistenten übersprungen werden.
6

Status abfragen

Frage den Freigabestatus ab, bis die Aufgabe bearbeitet wurde:
Bei status: "resolved" und executions[0].resultStatus: "success" ist die Rechnung finalisiert; resultMessage enthält die Belegnummer. Bei resultStatus: "failure" wurde die Rechnung nicht finalisiert (z. B. weil sie nach der Anfrage geändert wurde); erstelle in dem Fall eine neue Freigabe-Anfrage.
Eine genehmigte Rechnung ist rechtlich bindend und unveränderlich. Die manuelle Freigabe kann nicht aus dem MCP-Server heraus umgangen werden.

Audit

Jeder Tool-Aufruf über den MCP-Server wird automatisch protokolliert: Nutzerkonto, Organisation, Tool-Name, Parameter (ohne sensible Inhalte), Ergebnis und Ausführungsdauer. Der Audit-Log ist unveränderlich und dient der Nachvollziehbarkeit für Compliance-Anforderungen. Auch fehlgeschlagene oder abgelehnte Aufrufe werden erfasst.

DATEV

datev_export_status

Zeigt, ob ein DATEV-Cloud-Konto verbunden ist, und liefert für jeden Monat eine Zusammenfassung der exportierten und offenen Buchungen sowie den letzten Export-Status.

datev_cloud_export_start

Startet einen DATEV-Cloud-Export für einen oder mehrere Monate. Dieses Tool verändert Daten. Ohne confirm: true kommt eine Rückfrage zur Bestätigung zurück, es wird nichts ausgeführt.

Produktkatalog

product_tree

Liefert den Produktkatalog als Kategorie-Baum. Jeder Knoten enthält id, name, path, count (Anzahl Produkte) und children. Mit includeProducts: true zusätzlich eine flache Produktliste.
Sucht Produkte im Katalog. Teiltreffer auf Produktname, internen Namen und Produktnummer.

product_prices

Liefert alle Preispläne eines Produkts in vollständiger Form. Die zurückgegebene Preisplan-ID ist genau die pricePlan-Referenz, die ein Angebots-Produkteintrag (subscriptionProposal) benötigt. Alle Beträge sind ganzzahlige Cent. Je Preisplan wird zurückgegeben: id, name, internalName, status, currency, chargeType, billingInterval, billingFrequency, payInAdvance, proRata, freeUnits, minimumCommitment und ein price-Block mit den Beträgen in Cent.

Angebote

Die Angebots-Tools unterscheiden sich in Lese- und Schreiboperationen. Lesende Tools (offer_get, offer_block_types) benötigen offer:read. Schreibende Tools (offer_create, offer_update, offer_add_block, offer_update_block, offer_remove_block, offer_upload_image) benötigen offer:write. Angenommene oder archivierte Angebote sind unveränderlich.

offer_block_types

Listet alle unterstützten Block-Typen mit Metadaten auf (ob der Block atomar ist, ob er in PDF und Dokument erlaubt ist, und welche Attribute er akzeptiert). Mit optionalem type kommt zusätzlich ein konkretes Beispiel-Node zurück, das direkt an offer_add_block übergeben werden kann.

offer_get

Liest den Zustand eines Angebots effizient: Einstellungen (ID, Nummer, Name, Status, Anzeigesprache, Kunde, Gültigkeitsdatum, Annahme-Modus, Variablen) und eine kompakte Abschnitts- und Block-Übersicht. Mit sectionIndex (und optional blockIndex) wird zusätzlich der rohe JSON-Body genau dieses Abschnitts oder Blocks zurückgegeben.

offer_create

Legt ein neues Angebot an. Alle Parameter sind optional: ein Angebot ohne Kunde ist ausdrücklich erlaubt.

offer_update

Aktualisiert die Einstellungen eines Angebots. Nur mitgesendete Felder werden geändert; fehlende Felder bleiben unverändert.

offer_add_block

Fügt einen Block in einen Angebots-Abschnitt ein. Den gültigen Block-Node erhältst du über offer_block_types. Hat das Angebot noch keine Abschnitte, wird automatisch einer angelegt.

offer_update_block

Ersetzt einen bestehenden Block vollständig durch den übergebenen Tiptap-Node.

offer_remove_block

Entfernt einen Block aus einem Abschnitt; die nachfolgenden Blöcke rücken auf.

offer_upload_image

Lädt ein Bild für die Verwendung in Angeboten hoch. Erlaubt sind PNG, JPEG, WebP und GIF (max. 5 MB, dekodiert). Der MIME-Typ wird aus den Bilddaten erkannt; die Dateiendung wird entsprechend erzwungen. SVG wird abgelehnt. Die Antwort enthält mediaId, url, filename und einen fertigen imageBlock, der direkt an offer_add_block übergeben werden kann.

Angebote mit KI erstellen: ein typischer Ablauf

So erstellst du mit einem KI-Assistenten ein vollständiges Angebot:
1

Angebot anlegen

Lege ein leeres Angebot für den gewünschten Kunden an:
Die Antwort enthält die offerId, die du für alle weiteren Aufrufe benötigst.
2

Passende Produkte finden

Suche im Produktkatalog nach dem gewünschten Produkt:
3

Preisplan ermitteln

Lade die Preispläne des gefundenen Produkts:
Die id des gewünschten Plans verwendest du im nächsten Schritt als pricePlan.
4

Produktblock hinzufügen

Füge einen subscriptionProposal-Block mit Produkt und Preisplan ein:
5

Textinhalte ergänzen

Füge Überschriften, Absätze oder Tabellen hinzu. Welche Block-Typen zur Verfügung stehen und wie ein gültiger Node aussieht, liefert offer_block_types.
6

Bild hochladen und einfügen

Lade ein Bild hoch und füge es direkt ein. Das Tool gibt einen fertigen imageBlock zurück:
Den zurückgegebenen imageBlock übergibst du als block an offer_add_block.
Alle Angebots-Tools respektieren den Lebenszyklus: ein angenommenes oder archiviertes Angebot kann nicht mehr verändert werden. Prüfe den Status vorab mit offer_get.