Buchhaltungsbutler MCP
This server lets AI assistants (Claude, Cursor, etc.) manage a BuchhaltungsButler accounting system via MCP by exposing the official API as categorized read/write/destructive tools.
đ Read-only: fetch accounts, cost locations, postings, receipts, transactions, creditors/debtors/postingaccounts, and assigned documents.
đ§Ÿ Create data: add receipts, transactions, accounts, cost locations, creditors, debtors, postingaccounts; upload base64 files; create invoices, drafts, and e-invoices; add free/receipt/transaction postings (including batches).
đ Link/unlink: assign or unassign receipts to transactions, assign receipts to free postings, and run batch assignments.
âïž Update/revert: edit cost locations, creditors, debtors, postingaccounts; unconfirm postings; restore deleted receipts.
đïž Destructive: delete cost locations (permanent), delete receipts (restorable), and cancel postings via storno.
đ Reports: create and retrieve BWA and sum/ledger reports (async).
đ Operationally safe: credentials stay server-side, rate-limiting stays under BB limits, and it supports Docker, stdio, HTTP, and optional bearer-token auth.
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 MCPShow 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 |
| â | (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
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): Die Datei wird als Base64-Zeichenkette im FeldfileĂŒbergeben.receipts_createlegt Belege ohne Datei an.BlĂ€ttern: Die meisten
list-Tools akzeptierenlimitundoffsetund melden die Gesamtzahl inrows.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.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
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name of the basic account. | |
| type | Yes | The type of the basic account. Accepted values: "cash", "bank/institution", "other". | |
| is_revision_safe | No | If you create a basic account of type cash, you can make this revision_safe. That means, you cannot remove already saved transactions without creating a cancellation transaction. NOTE: This will only work for cash accounts! If specified, the field will be validated. | |
| postingaccount_number | Yes | The postingaccount_number of the basic account. | |
| receipt_creates_transaction | No | If a receipt assigned to this basic account should automatically create a transaction, this parameter should be true. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| postingaccount_number | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses meaningful behavioral traits: 'Not idempotent: calling twice with the same name creates two accounts' and 'v1 offers no way to update or delete an account afterwards.' These add important behavioral constraints that are not fully captured by annotations alone and do not contradict the readOnlyHint/idempotentHint values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and generally well organized, but it repeats the idempotency warning twice and opens with a broad generic line about creating 'receipts, transactions, postings, invoices, master data' that is only loosely related to this specific tool. It earns a 3 because the structure is serviceable but contains redundant boilerplate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description does not need to explain return values. It covers the important operational context an agent needs: when to use it, what not to use it for, non-idempotency risks, the alternative sibling, and the endpoint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers 100% of parameter descriptions, including accepted type values and per-field notes. The description does not add new meaning for individual parameters, so it stays at the baseline for high schema coverage. The mention of 'bank, cash or credit-card' loosely maps to schema values but does not clarify parameter formats beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Use to register a new bank, cash or credit-card account before importing transactions for it' and explicitly distinguishes itself from 'postingaccounts_create'. It also clarifies it is not for chart-of-accounts entries, so an agent can tell it apart from the sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: 'Use to register a new bank, cash or credit-card account before importing transactions for it. It also gives exclusions and alternatives directly: 'Not for chart-of-accounts entries. To add a posting account number, use postingaccounts_create.' It even tells the agent to 'Check accounts_list first' before creating.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of accounts data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description reinforces this with 'READ-ONLY'. It adds useful behavioral context beyond the annotations: there is no update or delete endpoint in v1 and an account created here can only be listed afterwards, which helps set expectations despite the read-only nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, front-loaded with the read-only flag, and each section adds value. The bolded 'get all the accounts' repeats the title slightly, but the rest is focused and avoids unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and an output schema present, the description fully covers what an agent needs: what the tool returns conceptually, how it relates to transaction tools, and which sibling to use instead. The lifecycle note about missing update/delete endpoints adds completeness for a no-parameter read operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the input schema is empty, so parameter semantics are trivially satisfied. The description still adds relevant context by explaining that the output is used to resolve account names to the numeric account id expected by transaction tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb (list) and resource (bank, cash and credit-card accounts) and explicitly contrasts these with the chart of accounts, pointing to postingaccounts_list for posting account numbers. This clearly distinguishes it from sibling tools without requiring schema inspection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use the tool: to list accounts that transactions can be booked against and to resolve account names to numeric account ids. It also gives an explicit exclusion ('Not the chart of accounts') and names the alternative tool, postingaccounts_list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| comment_text | Yes | The comment text as a string between 2 and 210 characters. | |
| receipt_id_by_customer | No | The id_by_customer of the receipt. If specified, the field will be validated. | |
| transaction_id_by_customer | No | The id_by_customer of the transaction. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that this is a write operation that is not idempotent ('calling twice may create duplicates'), which aligns with the idempotentHint:false annotation but adds specific consequence. It also reveals the lack of read/edit/delete endpoints, which is not apparent from annotations. These are valuable behavioral insights beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat verbose, starting with a generic 'đĄ WRITE · creates data' block that applies to all write tools, then repeating the title. However, the key information (exactly-one constraint, limitation) is clearly presented. The structure is acceptable but could be tightened by removing the generic header.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the required parameter constraint, the use case, and the persistence limitation. It doesn't describe the output, but an output schema exists. For a simple comment-adding tool, the description is sufficiently complete, though it could mention error scenarios or the expected response format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds the critical mutual exclusivity rule: exactly one of transaction_id_by_customer or receipt_id_by_customer must be set. The schema merely lists them as optional, so the description provides essential semantics that prevent invalid calls. This goes beyond the schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Add comment to transaction or receipt.' It identifies the specific resource (comments) and the action (add), and provides a concrete use case ('record why a booking was categorised'). This distinguishes it from sibling tools that create other entities like transactions or receipts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly specifies the required condition: 'Exactly one of transaction_id_by_customer or receipt_id_by_customer must be set.' It also notes the limitation that v1 offers no read/edit/delete endpoints, so comments are only visible in the web app. While it doesn't explicitly say 'use this instead of X', the context is clear and the constraint is actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | An alphanumeric identifier for the cost location (max 10 chars) | |
| name | Yes | The name/description of the cost location |
Output Schema
| Name | Required | Description |
|---|---|---|
| code | No | blank |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate write and non-idempotent, but the description adds concrete consequences: 'calling twice may create duplicates' and the recommendation to check the list first. This goes beyond the annotation by explaining the risk and mitigation. Slight redundancy but still valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear heading and front-loaded warning. It repeats 'Not idempotent' twice, which is mildly redundant, but overall it's efficient and each sentence serves a purpose. The generic opening about creating records is somewhat redundant with the title and annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with only two parameters and has an output schema, so the description need not detail return values. It covers the core behavioral risk (duplicates) and provides usage guidance. Missing details like permissions or format specifics are not critical given the schema and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides full descriptions for both parameters (code and name) with 100% coverage. The description does not add any additional meaning or nuance about the parameters, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'add' and the resource 'cost location', and even gives the use case 'create a cost centre before referencing it from a posting'. It distinguishes itself from siblings like cost_locations_list, cost_locations_update, and cost_locations_delete by explicitly saying 'add'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool: 'Use to create a cost centre before referencing it from a posting.' It also warns against duplication and directs the agent to check cost_locations_list first, which is an explicit alternative and a condition for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | The cost location code |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already include destructiveHint=true and readOnlyHint=false, but the description adds significant context beyond that: the irreversibility ('Permanent. Unlike a deleted receipt there is no restore endpoint'), the requirement to confirm with the user, and a distinction between receipt deletes (restorable) and cost-location deletes (not). This goes beyond what annotations provide and helps the agent understand the consequences. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat verbose and repetitive. It states 'Delete a cost location' and then 'Use to remove a cost centre' which is essentially the same. The destructive warning at the beginning is duplicated in the body. The emoji and bold formatting add visual noise. However, it is structured in short paragraphs and includes the endpoint, which is useful. It could be trimmed but is not excessively long.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (has output schema: true), the description doesn't need to explain return values. The description covers the core aspects: the action, when to use it, the irreversibility, and the confirmation requirement. It also mentions the HTTP endpoint. It lacks any mention of preconditions (e.g., whether the cost location must exist or have no dependencies), but for a simple delete tool this is adequate. Overall it is fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter 'code' with a clear description ('The cost location code'). The tool description does not add any additional semantic meaning to the parameter beyond what the schema provides. Since schema coverage is 100%, the baseline is 3. The description doesn't mention format, examples, or related fields, but it's not necessary given the schema covers it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Delete' and the resource 'cost location' (also referred to as 'cost centre'). It distinguishes from siblings like cost_locations_list, cost_locations_create, and cost_locations_update by specifying the action. The first sentence is explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: 'Use to remove a cost centre that is no longer needed.' It also gives an important usage guideline: confirm with the user before calling, because the delete is permanent and has no restore endpoint. It doesn't explicitly say when not to use, but the purpose is clear enough for an agent to decide. It could have mentioned alternatives (e.g., update if the cost centre is still needed) but that is implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The code of one specific cost location. If provided, only the cost location with this code will be returned. | |
| limit | No | Set a limit of returned postings. NOTE: the maximum limit is 1000! | |
| offset | No | Set an offset for the returned postings. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of cost locations data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the bar is lower. The description adds useful behavior beyond those annotations: each request is capped at 1000 cost locations, and the response shape is described as row count plus an array. It also explicitly says 'Makes no changes to the accounting records,' aligning with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the read-only note, followed by purpose, response info, limit warning, and use case. It includes a minor redundant bold heading 'get cost locations' that duplicates the title, but overall every main sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple 3-parameter read-only tool, robust annotations, complete schema coverage, and existing output schema, the description covers the essential operational context: purpose, return contents, limit, and where the data applies. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents `code`, `limit`, and `offset`. The description reinforces the 1000 limit but does not add meaningful parameter-level meaning beyond what the schema already provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get cost locations for a specified customer account' and explicitly states the response contains returned row count and an array of cost locations data. It further clarifies its role as listing cost centres for the `cost_location` fields on posting tools, which distinguishes it from mutation siblings like cost_locations_create/update/delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: 'Use to list the cost centres available for the `cost_location` fields on the posting tools.' It also notes the 1000-item request limit, helping agents understand pagination needs. It does not explicitly mention when not to use it or name alternatives, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | The cost location code | |
| name | Yes | The updated name/description of the cost location |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that updates happen in placeclip, that sent fields are overwritten, and that a preceding read is needed for partial changes. Annotations already label it as a write and non-destructive operation; the description adds useful overwrite behavior without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the action and scope. It contains some redundancy with the repeated 'update cost location' heading and the endpoint line, but most sentences earn their place by adding behavioral guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given only two required parameters, an existing output schema, and annotations covering write/idempotency/non-destructiveness, the description is mostly complete. It lacks an example or clear explanation of how `code` behaves when changing a number, but that is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so `code` and `name` are already documented directly. The description adds the rename/number use case but does not clarify whether `code` is the record identifier or the new number, so it adds only marginal semantics over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States that it modifies existing cost locations in place, and specifies the target fields (name/description) and use cases (rename a cost centre or change its number). It is clearly distinct from create/list/delete siblings, though 'change its number' is ambiguous relative to the `code`/`name` schema fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent to use the tool for renaming or changing an existing cost centre, and instructs reading `cost_locations_list` first before a partial change. It does not explicitly name create/delete as alternatives, but the 'existing' wording makes the intended context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| creditors | Yes | an array of creditors, each creditor has the field declaration and validation from the single add/creditor endpoint |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | Success boolean |
| creditors | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, idempotentHint=false, and destructiveHint=false. The description adds valuable context beyond annotations: 'Not idempotent: calling twice may create duplicates,' 'v1 offers no delete endpoint, so a creditor created here can only be updated afterwards, never removed,' and advises checking creditors_list first. This adds meaningful behavioral detail without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise and well-structured with a clear header and bullet-like sentences. The initial generic write note ('đĄ WRITE · creates data') is somewhat redundant given the annotations, but it doesn't detract significantly. Each subsequent sentence adds specific value, and the content is front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (array parameter with many fields), the description covers the key points: usage, array format, non-idempotency, no-delete limitation, and the alternative tool. An output schema exists (though not provided), so return values are likely documented there. The description is complete enough for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds clarification on the array parameter: 'Takes one or many: pass an array of creditors in creditors. A single record is an array of one.' This explains the required array structure, which is not immediately obvious from the schema alone, providing extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create a creditor account' and 'Use to create one or more suppliers,' specifying the resource and action. It also explicitly differentiates from debtors_create by saying 'For customers you invoice, use debtors_create.' This makes the purpose unambiguous and distinguishes it from a key sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance: 'Use to create one or more suppliers,' and instructs to check creditors_list first due to non-idempotency. It names the alternative tool for customers (debtors_create), giving clear when-to-use vs. when-not-to-use direction. Also explains the array format for one or many records.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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; the response reports the total in rows, so page until you have seen that many rows. v1 offers no delete endpoint for creditors, so they can only be created, listed and updated.
Endpoint: POST /settings/get/creditors
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | limit of the results, default is 25 results | |
| offset | No | offset of the results, default is 0 |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of creditors |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description reinforces this with 'READ-ONLY: Fetches data. Makes no changes' and adds behavioral details beyond the annotations: pagination behavior ('the response reports the total in rows') and the lifecycle note that creditors can only be created, listed, and updated. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the read-only callout, followed by purpose, alternative, pagination, and lifecycle. There is minor redundancy (read-only line + heading + 'Get all creditors'), but each section contributes distinct value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter list call with an output schema and extensive annotations, the description covers purpose, use case, sibling differentiation, pagination behavior, and lifecycle constraints. Nothing an agent needs to correctly invoke the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds functional meaning to `limit` and `offset` by explaining the pagination contract and how the reported `rows` total guides paging. This goes beyond the basic schema descriptions without restating every default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get all creditors' and explains the intended use case: 'resolve a supplier name to the creditor id the receipt and posting tools expect.' It explicitly differentiates from the sibling `debtors_list', leaving no ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly says when to use this toolâto list suppliersâand explicitly names the alternative for customers: 'For customers you invoice, use debtors_list.' It also gives practical pagination guidance ('page until you have seen that many rows'). This is strong, explicit usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| bic | No | The new bic of the creditor account. If specified, the field will be validated. | |
| zip | No | The new zip of the creditor account. If specified, the field will be validated. | |
| city | No | The new city of the creditor account. If specified, the field will be validated. | |
| iban | No | The new iban of the creditor account. If specified, the field will be validated. | |
| name | No | The new name of the creditor account | |
| No | The email of the creditor account. If specified, the field will be validated. | ||
| street | No | The new street of the creditor account. If specified, the field will be validated. | |
| country | No | The new country of the creditor account. If specified, the field will be validated. Valid cases are only the German version of the country name [DĂ€nemark] OR the two digit ISO code of the country [DK]. | |
| due_in_days | No | The due in days of your new debtor account. If specified, the field will be validated. | |
| sales_tax_id | No | The new sales tax id of the creditor account. If specified, the field will be validated. | |
| contact_person_name | No | The new contact person name of the creditor account. If specified, the field will be validated. | |
| postingaccount_number | Yes | The postingaccount_number of the creditor account | |
| additional_address_line | No | The new additional address line of the creditor account. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | the updated Debitor |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important behavioral traits beyond the annotations: it is a write operation ("WRITE · updates data"), modifies existing master data in place, and overwrites the fields sent. It also warns to read the current record before partial updates. Annotations already signal readOnlyHint=false and idempotentHint, so the description adds useful overwrite semantics without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and mostly focused, with the core purpose and key behavioral warning front-loaded. There is minor redundancy between the title, bold header, and first sentence, but overall the structure is efficient and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the full schema coverage and existing annotations, the description includes the crucial operational context: which fields can be updated, the overwrite behavior, the need to read first for partial changes, and the endpoint. It does not explain validation rules, but those are captured in the schema, and an output schema exists, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents all 13 parameters with their individual meanings and validations. The description adds only a high-level grouping (address, bank details, payment terms) and does not materially enhance parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: "Update a creditor account" and further clarifies the scope with "change a supplier's address, bank details or payment terms." This distinguishes it from sibling tools like creditors_create and creditors_list through the explicit focus on modifying existing creditor data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use the tool (to change supplier address, bank details, or payment terms) and advises reading the current record with creditors_list first for partial changes. It does not explicitly mention when not to use it or alternatives like creditors_create, but the usage intent is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| debtors | Yes | an array of debtors, each debtor has the field declaration and validation from the single add/debtor endpoint |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| debtors | No | |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations by explaining the non-idempotent behavior ('calling twice may create duplicates') and the lack of a delete endpoint ('can only be updated afterwards, never removed'). It also flags the write nature. This is valuable context not available from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but each sentence serves a purpose: it states the operation, distinguishes from the alternative, explains batch usage, warns about idempotency, and notes the lack of deletion. The use of bold headings and bullet-like phrasing keeps it scannable, though the initial broad statement about creating multiple record types is slightly extraneous.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description doesn't need to explain return values. It covers the essential operational details: batch capability, idempotency risk, deletion limitation, and the alternative tool. No critical information for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides detailed field descriptions, but the tool description clarifies the batch usage: 'pass an array of debtors in debtors. A single record is an array of one.' This adds practical meaning beyond the schema's generic array description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create a debtor account' and 'Use to create one or more customers,' providing a specific verb and resource. It explicitly distinguishes from the sibling tool creditors_create, making it unambiguous which tool to select.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'For suppliers you buy from, use creditors_create' and advises checking debtors_list first due to non-idempotency. This gives clear when-to-use and when-not-to-use guidance, as well as a recommended pre-check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | limit of the results, default is 25 results | |
| offset | No | offset of the results, default is 0 |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of debitors |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description reinforces those. It adds useful behavioral context beyond the annotations: support for limit/offset, the version limitation that debtors can only be created/listed/updated, and the POST endpoint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the read-only notice and core purpose. Some redundancy exists with the annotations and the repeated 'get debitors' heading, but it remains compact and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with two optional parametersmates and an existing output schema, the description provides everything an agent needs: purpose, use case, alternative tool, pagination support, and API endpoint. No critical call context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both limit and offset already have clear descriptions and defaults. The description only says 'Supports limit and offset' without adding new semantic information, so it stays at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the operation as retrieving debtors/customers ('Get all debitors', 'list customers') and names the specific resource it operates on. It also distinguishes the tool from creditors_list by explicitly contrasting customers vs suppliers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit use case ('resolve a customer name to the debtor id the receipt and posting tools expect') and an explicit alternative ('For suppliers you buy from, use creditors_list'). It also notes the API limitation around no delete endpoint, helping an agent understand scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| bic | No | The new bic of the debtor account. If specified, the field will be validated. | |
| zip | No | The new zip of the debtor account. If specified, the field will be validated. | |
| city | No | The new city of the debtor account. If specified, the field will be validated. | |
| iban | No | The new iban of the debtor account. If specified, the field will be validated. | |
| name | No | The new name of the new debtor account | |
| No | The email of the debtor account. If specified, the field will be validated. | ||
| street | No | The new street of the debtor account. If specified, the field will be validated. | |
| country | No | The new country of the debtor account. If specified, the field will be validated. Valid cases are only the German version of the country name [DĂ€nemark] OR the two digit ISO code of the country [DK]. | |
| sales_tax_id | No | The new sales tax id of the debtor account. If specified, the field will be validated. | |
| customer_number | No | The new customer_number of the debtor account. If specified, the field will be validated. | |
| contact_person_name | No | The new contact person name of the debtor account. If specified, the field will be validated. | |
| postingaccount_number | Yes | The postingaccount_number of the debtor account | |
| additional_address_line | No | The new additional address line of the debtor account. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | the updated Debitor |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a write operation, but the description adds valuable behavioral context: it modifies data 'in place' and overwrites only the fields sent, with a caution to read first for partial changes. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the write nature and core behavior first. Minor redundancy exists ('update debtor' appears in the heading, bold line, and prose sentence), but the overwrite warning and read-first hint earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 13 parameters, output schema, and annotations, the description covers the essential operational semantics: it is an update, it overwrites sent fields, it is for master data, and a read-first step is recommended. It does not discuss validation or response behavior, but the schema and annotations cover those details sufficiently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter. The description adds only high-level groupings ('address, bank details or customer number') that map loosely to parameters, but does not provide deeper meaning beyond what the schema contains.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Update a debtor account') and a concrete resource, with explicit examples of what can be changed: address, bank details, or customer number. This clearly distinguishes it from sibling update tools like creditors_update or postingaccounts_update.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear when-to-use guidance: changing existing debtor master data, and explicitly recommends reading the current record with debtors_list before a partial change. It does not explicitly mention when not to use it or alternatives like debtors_create, but the update-focused wording makes the intended scope reasonably clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| zip | No | The zip of the recipient company. If specified, the field will be validated. | |
| city | No | The city of the recipient company. If specified, the field will be validated. | |
| date | Yes | The date of the invoice. | |
| type | Yes | Can be either 'invoice' ("Rechnung"), 'credit' ("Gutschrift") or 'offer' ("Angebot"). | |
| No | The email for sending the invoice. If specified, the field will be validated. | ||
| street | No | The street of the recipient company. If specified, the field will be validated. | |
| country | No | The country of the recipient company. If specified, the field will be validated. Valid cases are only the German version of the country name [DĂ€nemark] OR the two digit ISO code of the country [DK]. | |
| due_days | No | The number of days between the invoice date and the due date. If specified, the field will be validated. | |
| item_vat | Yes | An array of invoice item vats. Usage: "item_vat" : ['7', '19'] Valid vat rates are floating point numbers between 0 and 100. | |
| language | No | The language for translatable invoice labels (e.g. headings, table headers, payment terms). Can be either 'de_DE' ("Deutsch", default) or 'en_US' ("English"). If omitted, German is used. | |
| item_name | Yes | An array of invoice items. Usage: "item_name" : ['Item 1', 'Item 2'] | |
| item_unit | Yes | An array of invoice items units. Usage: "item_unit" : ['Std.', 'Stk.'] | |
| item_amount | Yes | An array of invoice item amounts. Usage: "item_amount" : ['10', '20'] | |
| company_name | Yes | The company name of the recipient. | |
| discount_type | No | The type of the discount. Can be either 'percent' or 'EUR'. If specified, the field will be validated. | |
| invoicenumber | No | The invoicenumber for the invoice. If not specified, the default BHB number will be created. If specified, the field will be validated. | |
| show_bankdata | No | Show the the bank data on the invoice. If specified, the field will be validated. | |
| correspondence | No | The optional correspondence to the invoice recipient. If specified, the field will be validated. | |
| date_of_supply | No | Date or period of service/delivery. NOTE: The date_of_supply will be displayed on the PDF, but when the date AND the date_of_supply is specified in the format "YYYY-MM-DD", the date_of_supply will also be taken over as date_delivery of the receipt in the 'Belege' or 'Belege/Buchen' view. IMPORTANT: Due to the DATEV compatibility, we cannot accept a date_of_supply that is after the invoice date. In that case it will be ignored! | |
| discount_value | No | The value of granted discount. If specified, the field will be validated. | |
| customer_number | No | The customer number of the recipient. If specified, the field will be validated. | |
| final_provisions | No | The final comment of the invoice. If specified, the field will be validated. | |
| item_description | No | An array of invoice item description. Usage: "item_description" : ['Description Item 1', 'Description Item 2']. If specified, the field will be validated. | |
| show_contactdata | No | Show the contact data on the invoice. If specified, the field will be validated. | |
| show_prices_type | Yes | Can be either 'net' ("Netto") or 'gross' ("Brutto"). | |
| item_single_price | Yes | An array of invoice item single_prices. Usage: "item_single_price" : ['20', '19.99'] | |
| payment_reference | No | The payment reference id. If specified correctly, the resulting receipt of the created invoice will match with the corresponding transaction. NOTE: Currently we support Amazon order id, PayPal transaction id and Stripe transaction id! | |
| payment_conditions | No | The payment conditions of the invoice. If specified, the field will be validated. | |
| recurring_interval | No | An interval for recurring invoices. Can be either 'weekly', 'monthly', 'quarterly' or 'yearly'. If specified, the field will be validated. | |
| contact_person_name | No | The name of the contact person of the recipient company. If specified, the field will be validated. | |
| recurring_date_next | No | The next date of a recurring invoice. IMPORTANT: The field is required, if "recurring_interval" is specified. If specified, the field will be validated. | |
| additional_addressline | No | The additional address information of the recipient company. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| file_name | No | Filename of the created invoice |
| invoicenumber | No | blank |
| id_by_customer | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=false, idempotentHint=false, destructiveHint=false. The description adds concrete behavioral context: creates data, not idempotent (a second call issues a second invoice with a new number), and v1 offers no endpoint to list/change/cancel. This goes beyond the annotation flags and gives practical operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficient: it opens with a generic write warning, then a bold 'create invoice' heading, and a concise paragraph covering purpose, alternatives, and caveats. It's slightly longer than necessary but each sentence adds valueâno fluff. The key differentiators are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 32 parameters (9 required) and a rich output schema, the description covers purpose, usage guidance, behavioral caveats, and alternatives. The schema handles parameter details, so nothing critical is missing. The agent can decide when to invoke and what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already explains every parameter. The description does not add parameter-specific semantics beyond what the schema provides, though it does mention the 'type' (invoice/credit/offer) implicitly through 'final outgoing invoice'. Baseline 3 is appropriate since the schema carries the parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates invoices for a specified customer, and explicitly distinguishes it from siblings (invoices_create_draft, invoices_create_e_invoice) by noting when to use each. The verb 'create' and resource 'invoice' are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool (final outgoing invoice that is booked immediately) and when not to (for editable drafts or structured XML e-invoices), naming the alternative tools. It also warns about non-idempotency and lack of list/change/cancel endpoints, which informs usage decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| zip | No | The zip of the recipient company. If specified, the field will be validated. | |
| city | No | The city of the recipient company. If specified, the field will be validated. | |
| date | Yes | The date of the invoice. | |
| type | Yes | Can be either 'invoice' ("Rechnung"), 'credit' ("Gutschrift") or 'offer' ("Angebot"). | |
| No | The email for sending the invoice. If specified, the field will be validated. | ||
| street | No | The street of the recipient company. If specified, the field will be validated. | |
| country | No | The country of the recipient company. If specified, the field will be validated. Valid cases are only the German version of the country name [DĂ€nemark] OR the two digit ISO code of the country [DK]. | |
| item_vat | Yes | An array of invoice item vats. Usage: "item_vat" : ['7', '19'] Valid vat rates are floating point numbers between 0 and 100. | |
| language | No | The language for translatable invoice labels (e.g. headings, table headers, payment terms). Can be either 'de_DE' ("Deutsch", default) or 'en_US' ("English"). If omitted, German is used. | |
| item_name | Yes | An array of invoice items. Usage: "item_name" : ['Item 1', 'Item 2'] | |
| item_unit | Yes | An array of invoice items units. Usage: "item_unit" : ['Std.', 'Stk.'] | |
| item_amount | Yes | An array of invoice item amounts. Usage: "item_amount" : ['10', '20'] | |
| company_name | Yes | The company name of the recipient. | |
| discount_type | No | The type of the discount. Can be either 'percent' or 'EUR'. If specified, the field will be validated. | |
| show_bankdata | No | Show the the bank data on the invoice. If specified, the field will be validated. | |
| correspondence | No | The optional correspondence to the invoice recipient. If specified, the field will be validated. | |
| date_of_supply | No | Date or period of service/delivery. NOTE: The date_of_supply will be displayed on the PDF, but when the date AND the date_of_supply is specified in the format "YYYY-MM-DD", the date_of_supply will also be taken over as date_delivery of the receipt in the 'Belege' or 'Belege/Buchen' view. IMPORTANT: Due to the DATEV compatibility, we cannot accept a date_of_supply that is after the invoice date. In that case it will be ignored! | |
| discount_value | No | The value of granted discount. If specified, the field will be validated. | |
| customer_number | No | The customer number of the recipient. If specified, the field will be validated. | |
| final_provisions | No | The final comment of the invoice. If specified, the field will be validated. | |
| item_description | No | An array of invoice item description. Usage: "item_description" : ['Description Item 1', 'Description Item 2']. If specified, the field will be validated. | |
| show_contactdata | No | Show the contact data on the invoice. If specified, the field will be validated. | |
| show_prices_type | Yes | Can be either 'net' ("Netto") or 'gross' ("Brutto"). | |
| item_single_price | Yes | An array of invoice item single_prices. Usage: "item_single_price" : ['20', '19.99'] | |
| payment_conditions | No | The payment conditions of the invoice. If specified, the field will be validated. | |
| recurring_interval | No | An interval for recurring invoices. Can be either 'weekly', 'monthly', 'quarterly' or 'yearly'. If specified, the field will be validated. | |
| contact_person_name | No | The name of the contact person of the recipient company. If specified, the field will be validated. | |
| recurring_date_next | No | The next date of a recurring invoice. IMPORTANT: The field is required, if "recurring_interval" is specified. If specified, the field will be validated. | |
| additional_addressline | No | The additional address information of the recipient company. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds concrete behavioral details beyond the annotations: 'Not idempotent: calling twice may create duplicates,' 'A draft is not booked and carries no invoice number,' and 'Releasing happens in the web app.' These are nuances not captured by the annotations (readOnlyHint=false, idempotentHint=false, openWorldHint=true) and are valuable for agents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear front-loaded write warning, purpose statement, use-case, and endpoint. It is slightly verbose (the generic 'WRITE · creates data' prelude is not tool-specific), but every other sentence earns its place. Overall, it is concise enough for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high parameter complexity, an output schema, and a rich set of sibling tools, the description covers the essential context: the draft workflow, the non-idempotence, and the explicit alternative for final invoices. It does not explain return formats, but the output schema exists to cover that. The only minor gap is that it doesn't mention other invoice-related siblings like invoices_create_e_invoice, but that is not necessary for selecting this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents every parameter thoroughly. The description provides no additional parameter-level information, but per the rubric the baseline is 3 when the schema carries the burden. The description does not introduce ambiguity or omissions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Add an invoice draft'), the resource ('for the specified customer'), and clearly distinguishes itself from the sibling tool invoices_create by explaining the difference (draft vs. final invoice). It also notes that drafts are not booked and have no invoice number, making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly describes when to use this tool: 'Use to prepare an invoice that a human should review and release' and contrasts it directly with the alternative: 'To issue a final invoice directly, use invoices_create.' Additionally, it states that v1 offers no listing/editing/release endpoints, informing the user of workflow limitations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| zip | Yes | The zip of the recipient company. If specified, the field will be validated. | |
| city | Yes | The city of the recipient company. If specified, the field will be validated. | |
| date | Yes | The date of the invoice. | |
| type | Yes | Can be either 'invoice' ("Rechnung"), 'credit' ("Gutschrift") or 'offer' ("Angebot"). | |
| Yes | The email for sending the invoice. If specified, the field will be validated. | ||
| street | Yes | The street of the recipient company. If specified, the field will be validated. | |
| country | Yes | The country of the recipient company. If specified, the field will be validated. Valid cases are only the German version of the country name [DĂ€nemark] OR the two digit ISO code of the country [DK]. | |
| due_days | No | The number of days between the invoice date and the due date. If not specified due date will be set to invoice date (due_days = 0). | |
| language | No | The language for translatable invoice labels (e.g. headings, table headers, payment terms). Can be either 'de_DE' ("Deutsch", default) or 'en_US' ("English"). If omitted, German is used. | |
| item_name | Yes | An array of invoice items. Usage: "item_name" : ['Item 1', 'Item 2'] | |
| item_unit | Yes | An array of invoice items units. Usage: "item_unit" : ['Std.', 'Stk.'] | |
| item_amount | Yes | An array of invoice item amounts. Usage: "item_amount" : ['10', '20'] | |
| company_name | Yes | The company name of the recipient. | |
| e_invoice_id | Yes | Buyer reference (default: 0). If you do not have a reference, please enter "0". A valid is mandatory for e-invoices to public contracting authorities and is provided by the recipient. | |
| discount_type | No | The type of the discount. Can be either 'percent' or 'EUR'. If specified, the field will be validated. | |
| invoicenumber | No | The invoicenumber for the invoice. If not specified, the default BHB number will be created. If specified, the field will be validated. | |
| item_tax_type | Yes | An array of invoice item tax types. Usage: "item_vat" : ['S', 'E'] Valid tax types are the following: S - VAT (standard rate) Z - 0% VAT AE - Reverse Charge (§13b) K - EU Supply (Intra-community supply) G - Third Country Supply (Export) E - VAT Exempt Supply & Services | |
| show_bankdata | No | Show the the bank data on the invoice. If specified, the field will be validated. | |
| correspondence | No | The optional correspondence to the invoice recipient. If specified, the field will be validated. | |
| date_of_supply | No | Date or period of service/delivery. NOTE: The date_of_supply will be displayed on the PDF, but when the date AND the date_of_supply is specified in the format "YYYY-MM-DD", the date_of_supply will also be taken over as date_delivery of the receipt in the 'Belege' or 'Belege/Buchen' view. IMPORTANT: Due to the DATEV compatibility, we cannot accept a date_of_supply that is after the invoice date. In that case it will be ignored! | |
| discount_value | No | The value of granted discount. If specified, the field will be validated. | |
| customer_number | No | The customer number of the recipient. If specified, the field will be validated. | |
| item_tax_amount | Yes | Only required if corresponding item_tax_type = 'S' (VAT). An array of invoice item vats. Usage: "item_tax_amount" : ['7', '19'] Valid vat rates are floating point numbers between 0 and 100. | |
| final_provisions | No | The final comment of the invoice. If specified, the field will be validated. | |
| item_description | No | An array of invoice item description. Usage: "item_description" : ['Description Item 1', 'Description Item 2']. If specified, the field will be validated. | |
| show_contactdata | No | Show the contact data on the invoice. If specified, the field will be validated. | |
| show_prices_type | Yes | Can be either 'net' ("Netto") or 'gross' ("Brutto"). | |
| item_single_price | Yes | An array of invoice item single_prices. Usage: "item_single_price" : ['20', '19.99'] | |
| payment_reference | No | The payment reference id. If specified correctly, the resulting receipt of the created invoice will match with the corresponding transaction. NOTE: Currently we support Amazon order id, PayPal transaction id and Stripe transaction id! | |
| payment_conditions | No | The payment conditions of the invoice. If specified, the field will be validated. | |
| recurring_interval | No | An interval for recurring invoices. Can be either 'weekly', 'monthly', 'quarterly' or 'yearly'. If specified, the field will be validated. | |
| contact_person_name | No | The name of the contact person of the recipient company. If specified, the field will be validated. | |
| recurring_date_next | No | The next date of a recurring invoice. IMPORTANT: The field is required, if "recurring_interval" is specified. If specified, the field will be validated. | |
| additional_addressline | No | The additional address information of the recipient company. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| file_name | No | Filename of the created invoice |
| invoicenumber | No | blank |
| id_by_customer | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate readOnlyHint=false and idempotentHint=false, and the description adds meaningful behavioral context: 'Not idempotent: calling twice may create duplicates' and 'v1 offers no endpoint to list or cancel an e-invoice once created.' This tells the agent the write is non-reversible through the API, which is valuable beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the write nature, definition, use case, alternative, and caveat. It is slightly redundant: 'Not idempotent' is repeated twice, but the rest is purposeful and well organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a large 34-parameter tool with 16 required parameters, the schema carries most of the invocation burden, and the description supplies the missing selection context: when to choose e-invoice vs `invoices_create`, the no-list/no-cancel caveat, and the endpoint. It could mention `invoices_create_draft` as another sibling option, but that is not essential for correct use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% schema description coverage, so the description does not need to repeat parameter details. The description only refers generically to 'the specified customer' and does not add parameter-level meaning beyond the schema, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'Add an e-invoice for the specified customer.' It also differentiates from the sibling tool `invoices_create` by explicitly saying that ordinary PDF invoices should use that tool instead, so an agent can immediately distinguish the two.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit when-to-use condition: when the recipient requires a structured electronic invoice, with a concrete example (German public-sector customer expecting XRechnung). It also names the alternative (`invoices_create` for ordinary PDF invoices) and warns about the non-reversibility limitation, which helps prevent misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name of your new postingaccount. | |
| postingaccount_number | Yes | The postingaccount number of your new postingaccount. | |
| parent_postingaccount_number | Yes | The parent postingaccount number of your new postingaccount.This is the postingaccount from which your individually created postingaccount inherits their properties. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| postingaccount_number | No | blank |
| parent_postingaccount_number | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, idempotentHint=false, and destructiveHint=false. The description adds context beyond these: 'v1 offers no delete endpoint, so a posting account created here can only be updated afterwards.' This clarifies the consequence of non-idempotency and the tool's limitations, adding value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a bolded heading and front-loaded warning about writes and idempotency. While slightly long, every sentence adds value (purpose, usage, constraint, endpoint). It is efficient and not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema covering return values, and the description provides the endpoint, usage guidance, and important constraints (non-idempotent, no delete). It also distinguishes from related tools. For a simple create operation with three well-documented parameters, nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with each parameter having a meaningful description. The tool description does not add extra semantic detail beyond the schema, so the baseline of 3 is appropriate. It doesn't need to compensate because the schema fully documents the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create a postingaccount' and specifies its purpose: 'add an account number to the chart of accounts that the standard chart does not cover.' It distinguishes from accounts_create, which is for bank or cash accounts, making the tool's unique function unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool ('Use to add an account number to the chart of accounts that the standard chart does not cover') and when not ('To register a bank or cash account, use accounts_create'). Also mentions the lack of delete endpoint, guiding usage expectations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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, so page until rows is covered or filter instead. v1 offers no delete endpoint for posting accounts.
Endpoint: POST /settings/get/postingaccounts
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | limit of the results, default is 1000 results. If specified, the field will be validated. | |
| order | No | the order of the results.The following options are valid:postingaccount_number ASC | DESCname ASC | DESCtype ASC | DESC. If specified, the field will be validated. | |
| offset | No | offset of the results, default is 0. If specified, the field will be validated. | |
| exclude_debtors | No | exclude all debtor postingaccounts from result. If specified, the field will be validated. | |
| exclude_accounts | No | exclude all base accounts (e.g. bank accounts) from result. If specified, the field will be validated. | |
| exclude_creditors | No | exclude all creditor postingaccounts from result. If specified, the field will be validated. | |
| exclude_postingaccounts | No | exclude all postingaccounts from result. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of postingaccounts data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotent, and non-destructive, and the description reinforces READ-ONLY and adds context beyond that: pagination support, the need to page until all rows are covered, and the absence of a delete endpoint. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is informative and well-structured, with the READ-ONLY notice front-loaded. Though it includes some repetition of the tool name, every major section earns its place and it is not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and all parameters are documented in the schema, the description provides enough context for correct invocation: purpose, use case, alternative tool, pagination behavior, and endpoint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema fully documents each parameter. The description adds practical meaning around `limit` and `offset` by explaining the large size of a chart and advising to page until `rows` is covered.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get all postingaccounts' and clarifies this is the chart of accounts. It explicitly distinguishes itself from `accounts_list` for bank accounts, so an agent can tell siblings apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete use case: finding a posting account number before booking office supplies. It also names when to use a different tool (`accounts_list`) and explains pagination strategy because the full chart can run to several hundred rows.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The new name of the postingaccount to update. | |
| postingaccount_number | Yes | The postingaccount number of the postingaccount to update. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | the updated postingaccount |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds the critical behavioral detail that it 'overwrites the fields you send,' which goes beyond what annotations state. It also advises reading the record first, indicating the overwrite semantics. This is consistent with readOnlyHint: false and doesn't contradict any annotation. It doesn't mention idempotency, but that's already covered by idempotentHint: true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loads key information like the overwrite behavior and the advice to read the record first. The structure is clear with a heading and bullet. However, it starts with an emoji and 'WRITE' which adds visual noise and is unnecessary, slightly detracting from conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple update tool with two parameters and an output schema, the description covers purpose, usage, and the crucial overwrite behavior. It doesn't discuss error handling or non-existent records, but that's not essential for this simple operation. The guidance to read the record first is valuable. Overall, it's complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both parameters with clear descriptions (name = new name, postingaccount_number = number to update). The description mentions 'rename a posting account or change its properties' but doesn't add parameter-specific detail beyond what the schema provides. Since schema coverage is 100%, the description adds little value here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates an existing postingaccount, with specific use cases (rename or change properties). It distinguishes from the list tool by referencing postingaccounts_list for reading, and the verb 'update' is precise. While it doesn't explicitly contrast with postingaccounts_create, the name and context make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear guidance on when to use: for renaming or changing properties. It also advises reading the current record first for partial changes, which is a practical tip. It doesn't explicitly name alternatives like postingaccounts_create, but the context implies that creation would be a different tool, so it's effective.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| posting_id_by_customer | Yes | The id_by_customer of the posting. | |
| receipt_id_by_customer | Yes | The id_by_customer of the receipt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the operation links/unlinks records, is reversible, and is a write operation (đĄ WRITE). It also notes the endpoint. Annotations already indicate readOnlyHint=false and destructiveHint=false, and the description adds the reversible and link/unlink semantics, which go beyond the annotations. Minor gap: no detail on side effects or idempotency, but the reversible note is valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the write/reversible warning, then the purpose, then the alternative. The endpoint line is slightly redundant with the tool name but adds useful routing info. No wasted sentences, though the emoji and repeated title could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 2-parameter link operation with full schema coverage and an output schema, the description covers the core use case, the alternative, and the reversibility. It doesn't explain what the response contains, but the output schema exists, so that burden is not on the description. The only missing context is any prerequisite (e.g., the posting must be free), which is implied by the name but not explicitly stated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description does not add extra meaning about the parameters beyond their names and schema descriptions. Baseline 3 is appropriate because the schema carries the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'assign' and the resource 'receipt to a free posting', and explains the purpose: attaching a receipt to a free posting that was booked without one. It also distinguishes itself from the sibling transactions_assign_receipts, which is a different target resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool: to attach a receipt to a free posting booked without a supporting document. It also names the alternative tool (transactions_assign_receipts) and the condition for choosing it (linking to a bank transaction instead). This is clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| posting_id_by_customer | Yes | The id_by_customer of the posting. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | Success message |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the destructiveHint annotation by explaining what happens to fixed vs non-fixed postings, the two-visible-entries consequence of reversals, and the requirement to confirm with the user. The note that 'receipt deletes are restorable; cost-location deletes are not' adds context but is somewhat disconnected from a postings-cancel operation and could cause confusion.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the destructive warning and confirmation requirement, which is good. However, the fixed/unfixed deletion vs reversal behavior is explained multiple times in different paragraphs, and the endpoint line plus generic delete preamble add redundancy that could be trimmed without losing safety-critical information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with an output schema and safety annotations, the description covers purpose, side effects, user confirmation, and alternatives to sibling tools. It stops short of top marks because the restorability sentence feels tangential and idempotency is only implied by annotations, not clarified in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage for the single parameter, describing it as 'The id_by_customer of the posting.' The description does not add further semantic detail about where this identifier comes from or how it resolves to a posting, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Identifies the exact operation ('Cancel a specified posting') and the resource it acts on phosphorylate. It also distinguishes itself from the postings_unconfirm_* sibling tools by explaining the deletion vs reversal semantics, so an agent can disambiguate purely from the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool ('Use to take a booking out of the books entirely') and contrasts it with alternative unconfirm tools, including a concrete preference rule ('Prefer unconfirming when the goal is to edit and rebook'). It also instructs the agent to confirm with the user before calling, which is strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| receipts | Yes | an array of receipt postings, each receipt posting has the same field declaration and validation as the postings/add/receipt endpoint |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | Success boolean |
| receipts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and idempotentHint=false, and the description repeats the 'Not idempotent' trait. However, it adds valuable context beyond annotations: reversibility with `postings_unconfirm_for_receipt` while not fixed, the foreign currency prerequisite, and the 'WRITE' marker. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-organized with headers, bolded key points, and a clear logical flow. Every sentence adds relevant information (prerequisites, array semantics, reversal). It is not overly verbose given the complexity of the operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all necessary steps: prerequisites (activation), special case (foreign currency), array structure, distinction from sibling tool, and reversal method. It does not explain return values, but an output schema exists, so that is not required. For a complex mutation tool, this is highly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema itself provides descriptions for each parameter, so coverage is high. The description adds crucial structural meaning beyond the schema: the positional relationship across arrays (index 0 of each describes the same split line) and the one-or-many array convention. This clarifies usage not evident from individual parameter schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Add postings for a specified receipt' and 'book one or more receipts that already exist', distinguishing it from `postings_create_free` which is for journal entries without receipts. It also specifies the resource (receipts) and the action (adding postings), making it unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly explains when to use this tool (for existing receipts) and when not (use `postings_create_free` for journal entries without receipts). It also lists prerequisites (creditor/debtor posting activated) and a special condition (foreign currency requires fetching receipt first). No alternative is left vague.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| transactions | Yes | an array of transaction postings, each transaction posting has the same field declaration and validation as the postings/add/transaction endpoint |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | Success boolean |
| transactions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false. The description adds valuable behavioral context: 'đĄ WRITE · creates data', 'Not idempotent: calling twice may create duplicates', and 'Reversible with `postings_unconfirm_for_transaction` while the posting is not fixed.' It also mentions the endpoint. This goes beyond the annotations by explaining the non-idempotency consequence and the reversal path. It doesn't detail error conditions or side effects beyond duplicates, but the annotations plus description cover the key behavioral traits well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear warning header, a concise summary, usage guidance, and an endpoint reference. It is somewhat long but every section earns its place: the warning about non-idempotency, the alternative tool, the batch semantics, and the positional array constraint. The emoji and bold formatting help front-load the critical write/non-idempotent nature. It could be slightly tighter, but it's appropriately sized for a complex tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (nested arrays, positional constraints, multiple VAT options), the description covers the essential context: what it does, when to use it, the alternative, non-idempotency, reversibility, and batch behavior. The output schema exists, so return values don't need explanation. The only minor gap is that it doesn't explicitly state prerequisites (e.g., transaction must exist), but the schema's required fields and the reference to `transaction_id_by_customer` imply this. Overall, it's complete enough for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds meaningful context about the overall structure: 'The per-transaction arrays are positional and must all have the same length' and 'A single record is an array of one.' It also clarifies the batch nature of the `transactions` parameter. The schema itself is rich with per-field descriptions, so the description doesn't need to repeat them. The added structural guidance about positional arrays is valuable beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Add postings for a specified transaction' and 'book one or more bank transactions, splitting each across posting accounts, VAT rates and cost centres.' It distinguishes itself from the sibling `postings_create_free` by explicitly noting that this tool is for transactions with a bank transaction behind them, while `postings_create_free` is for journal entries without one. The verb 'add' and resource 'postings for a transaction' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: it says to use this tool to book bank transactions, and explicitly names the alternative `postings_create_free` for journal entries without a bank transaction. It also explains the batch behavior ('Takes one or many: pass an array of transactions in `transactions`. A single record is an array of one.') and the positional array requirement. This is clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| free_postings | Yes | an array of free postings, each free posting has the same field declaration and validation as the postings/add/free endpoint |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | Success boolean |
| free_postings | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=false, and the description reinforces this: 'Not idempotent: calling twice may create duplicates.' and 'Not idempotent, so a repeated call books the amount twice.' It adds context about attaching a receipt later via `postings_assign_receipt_to_free`, which is useful lifecycle information. No contradiction with annotations. The description provides practical behavioral implications beyond what annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear warning header, then a purpose statement, usage guidance, and batch/non-idempotency notes. It is somewhat long but every sentence adds useful informationâno filler. The most critical warnings (write, non-idempotent) are front-loaded, which is good for agent attention.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return format is defined. The description covers what the tool does, when to use it, batch behavior, non-idempotency, and related tools for attaching receipts. It does not mention potential errors or authentication, but those are not expected given the output schema and annotations. Overall it is complete enough for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with each parameter described in the schema, so the description doesn't need to restate them. It does add meaning by explaining the concept of a 'free' posting (you name both sides yourself via `postingaccount_debit` and `postingaccount_credit`) and clarifies that the `free_postings` parameter is an array even for a single posting. This adds semantic value beyond the schema's basic field definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that this tool adds free postings (debit/credit pairs not tied to a receipt or bank transaction) and explicitly distinguishes it from `postings_create_for_receipt` and `postings_create_for_transaction`. The verb 'add' plus the resource 'free posting' is specific, and it disambiguates against sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use it: '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.' It also states alternatives: 'If the booking documents a receipt, use postings_create_for_receipt. If it settles a bank transaction, use postings_create_for_transaction.' This fully covers when and when-not, and names the alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Set a limit of returned postings. NOTE: the maximum limit is 1000! | |
| order | No | Possible values are "default", "date ASC", "date DESC", "date_last_action ASC", "date_last_action DESC", "id_by_customer ASC", "id_by_customer DESC". The default order is ascending by date as first and date_last_action as second criterion. Please not that the validation of the specified value is case sensitive! | |
| offset | No | Set an offset for the returned postings. | |
| account | No | A comma separated list of accounts. Use the following options: all, all financial accounts, free booking and any of your available accounts as numeric value. The default is "all" | |
| date_to | Yes | The postings issuing date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All postings with issuing date including and before given value will be returned. If specified, the field will be validated. An empty string is not considered a valid date. | |
| date_from | Yes | The postings issuing date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All postings with issuing date including and after given value will be returned. If specified, the field will be validated. An empty string is not considered a valid date. | |
| cost_location | No | Set a specific cost location code. If specified, only postings to this cost location are returned | |
| posting_status | No | Set the status of the posting. You have the following options: all, fixed, unfixed The default is "all" | |
| postingaccount | No | A comma separated list of postingaccounts. Use the following options: all, all postingaccounts, all debtors, all creditors and any of your available postingaccounts as numeric value. The default is "all" | |
| date_last_action_to | No | A date in format 'YYYY-MM-DD'. All postings that were created or modified in status (confirmed, fixed) on or before this date will be returned. If specified, the field will be validated. An empty string is not considered a valid date. | |
| date_last_action_from | No | A date in format 'YYYY-MM-DD'. All postings that were created or modified in status (confirmed, fixed) on or after this date will be returned. If specified, the field will be validated. An empty string is not considered a valid date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of postings data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the description doesn't need to repeat safety traits. It adds the critical limit of 1000 postings per request, which is a behavioral constraint beyond annotations. It also mentions the response includes row count and an array, providing some transparency, though output schema likely covers details. This is good value beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, starting with a clear READ-ONLY flag, then a purpose statement, key limits, and usage advice. It is concise without excess, though it redundantly repeats 'get postings' in the description. Overall, it is efficiently organized and front-loaded with the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters with full schema coverage, an output schema, and safety annotations, the description is largely complete. It covers the core purpose, the 1000-row limit, and practical usage tips. It doesn't explain every parameter or edge case, but the schema and output schema fill those gaps. The description adequately complements the structured data for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are already documented in detail, including formats and defaults. The description's mention of 'Supports `limit` and `offset`' is redundant with the schema, and the advice about bounded date ranges is more usage guidance than parameter semantics. It adds minimal new meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action and resource: 'Get postings for a specified customer account' and 'read the booking journal'. It specifies a verb (get), a resource (postings), and a scope (customer account), making it distinct from sibling tools like postings_cancel or postings_create_*. The READ-ONLY label further disambiguates it from write operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use to read the booking journal, filtered by date range or posting account', providing clear context for when to invoke it. It also gives practical advice to 'Ask for a bounded date range rather than paging through a whole financial year', which is helpful guidance. However, it does not explicitly name alternatives or exclusions, though the sibling list makes the read/write distinction obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| receipt_id_by_customer | Yes | The id_by_customer of the receipt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | Success message |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that this is a state-reverting WRITE, explains it is reversible, keeps the posting, and clearly says it only clears confirmation. It goes beyond the annotations by describing the side effect and precondition, though the 'restore a deleted receipt' phrase adds ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than necessary and repeats the fixed-not-fixed condition twice, but it front-loads the most important behavioral context up front. Most sentences add useful information such as reversibility, use case, alternative, and endpoint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with a full input schema and an output schema, the description provides the essential behavior: what is changed, when it is allowed, and what it does not do. It could clarify behavior when the posting is already unconfirmed or fixed, but nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter and the input schema already fully describes `receipt_id_by_customer`. The description adds no extra semantic detail beyond referring to 'the receipt', so the schema carries the burden as expected at high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action: unconfirm receipt postings by receipt, and distinguishes itself from `postings_cancel` for removing a posting. The core resource and verb are unmistakable despite the slightly confusing 'restore a deleted receipt' phrase.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete use case: send a receipt posting back to unconfirmed state for correction. It also states the precondition that postings must not be fixed and points to `postings_cancel` as the alternative for removal. It does not explicitly contrast with `postings_unconfirm_for_transaction` or `postings_unconfirm_free`, but enough guidance is present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| transaction_id_by_customer | Yes | The id_by_customer of the transaction. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | Success message |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description adds useful behavioral context: the operation is reversible, it only clears confirmation rather than deleting the posting, and it only works while the posting is not fixed. The 'restore a deleted receipt' parenthetical is an inaccurate behavioral claim for this specific tool, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description repeats the fixed-posting condition twice ('This will only work if the postings are not fixed' and 'Only works while the posting is not fixed'), and overlaps 'Remove postings...' with 'Use to send a transaction posting back...' The opening line also adds padded, partly off-topic content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one fully documented parameter, an output schema, and annotations covering the write/idempotent/non-destructive profile, the description provides the essential invocation context: what it does, when it works, and which alternative to use for deletion. The out-of-scope receipt-restoration mention is the main thing keeping it from being fully clean.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for the only parameter, transaction_id_by_customer, which is already documented as 'The id_by_customer of the transaction.' The description merely refers generically to a 'specified transaction' and adds no new parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The core action is clear: 'Remove postings for a specified transaction by unconfirming them' and it explicitly distinguishes itself from deletion with 'To remove the posting itself, use postings_cancel.' However, the opening parenthetical 'restore a deleted receipt' references behavior that seems outside this transaction-posting tool's scope, slightly muddying the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says to use this tool when a transaction posting needs to be returned to the unconfirmed state for correction, and it gives the precondition that the postings must not be fixed. It also explicitly routes removal of the posting itself to postings_cancel, providing a clear alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| posting_id_by_customer | Yes | The id_by_customer of the free posting. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | Success message |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by explaining that this is a reversible state revert, that it keeps the posting, and that it only clears confirmation. It also discloses the fixed-posting restriction. The mention of 'restore a deleted receipt' is ambiguous and not consistently integrated with the rest of the behavior description, so it slightly weakens an otherwise transparent explanation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the WRITE indicator and core effect, which is good)Skip. However, it is repetitive: the fixed-posting constraint is stated twice ('This will only work if the posting is not fixed' and 'Only works while the posting is not fixed'), and the broad 'restore a deleted receipt' line adds ambiguity. It could be tightened without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with an output schema, the description is largely complete: it explains the effect, reversibility, the fixed-posting limitation, and the alternative for deletion. It does not define what 'fixed' means, and the confusing 'restore a deleted receipt' phrase is left unresolved, but overall an agent has enough context to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter, posting_id_by_customer, and the schema already describes it as 'The id_by_customer of the free posting.' The description refers to 'a specified free posting' but adds no new parameter-level detail beyond the schema, so the baseline 3 applies due to full schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The core purpose is clear: 'unconfirm free posting' and 'Remove a specified free posting by unconfirming it.' It also distinguishes itself from postings_cancel by noting that this tool keeps the posting while cancellation removes it. However, the opening line mentions 'restore a deleted receipt,' which is not clearly part of this tool's specific action and could mislead an agent about its scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it: to send a free posting back to the unconfirmed state so it can be corrected. It also gives a clear when-not condition: it only works if the posting is not fixed. It names a concrete alternative, postings_cancel, for when the posting itself should be removed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| receipts | Yes | list of receipts maximum of 50 receipts are allowed A receipt has the same fields like the /receipts/add endpoint has, same applies for error messages |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | is the request successful or faulty |
| receipts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations that already indicate non-idempotency, the description adds crucial behavioral details: repeated calls create duplicates, and the response reports per-item success so partial failures leave successful entries intact. This is value-added context not present in the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured with a clear warning prefix, a dedicated 'add a receipt' section, and line breaks for readability. However, it repeats the non-idempotency note twice, which is slightly redundant given the annotation already flags it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (write operation, one array parameter, output schema present), the description covers all necessary aspects: purpose, usage conditions, alternative tool, behavioral caveats, and input format. No critical information is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the receipts parameter thoroughly. The description merely restates the array input and points to the /receipts/add endpoint for field details, adding no new semantic meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('add') and resource ('receipt'), and clearly differentiates from the sibling receipts_upload by emphasizing 'without a file'. It also lists the broader effect ('creates new records') without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to use this tool ('Use this endpoint, to add a receipt without a file!') and when not, naming the alternative 'receipts_upload' for file-based receipts. It also clarifies the array input format, leaving no guesswork.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| id_by_customer | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint and readOnlyHint, but the description adds important context: it states the operation is destructive and requires user confirmation, clarifies that receipt deletes are restorable (unlike cost-location deletes), and describes the soft-delete nature ('mark as deleted'). It also mentions the behavior for cancelling postings, though that is tangential. This goes beyond the annotations and provides useful behavioral insight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than necessary and includes information about cost-location deletes and cancelling postings that is not directly relevant to this specific tool. The opening warning block repeats the destructive nature, and the text could be streamlined to focus on receipts_delete. However, it is front-loaded with the destructive warning and the core action is stated early.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there are no parameters and an output schema exists, the description covers the essential aspects: the action, how to get the identifier, when to use it, and restorability. It also includes the important user-confirmation requirement. It doesn't mention error cases or permissions, but for a simple delete operation with no params, this is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters in the input schema (0 properties). The description explains how to obtain the id_by_customer, which is essential for the call, even though it is not a request body parameter (likely a path parameter). Since there are no params, the baseline is 4, and the description adds value by explaining how to get the required identifier.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Mark a receipt as deleted for a specified customer account by id_by_customer.' It identifies the specific resource (receipt) and the key identifier (id_by_customer). It also distinguishes from restore by mentioning recoverability, and notes it is for removing a mistakenly filed receipt, so the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage guidance: it says to use this to remove a receipt filed by mistake, mentions the prerequisite of obtaining id_by_customer via '/receipts/get method', and instructs to confirm with the user before calling. It also contrasts with receipts_restore for recovery. However, it doesn't explicitly state when not to use it or compare with other deletion tools like cost_locations_delete, leaving some room for ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| get_file | No | If true, the file will be included as a base64 encoded string (e_invoice_type = 0 -> standard pdf file, e_invoice_type = 1 -> ZUGFeRD pdf file, e_invoice_type = 2 -> xRechnung xml file). If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of receipt data |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, and the description's READ-ONLY banner matches them. Beyond the annotations, it adds the per-customer counter semantics, the endpoint, and the fact that the response contains an array. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is reasonably compact and front-loads the read-only and single-receipt behavior, but it restates the same idea in the title-like line and in 'Use to fetch a single receipt...' after already saying it. A couple of redundant sentences could be merged without losing content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-optional-parameter tool with an output schema and strong annotations, the description is nearly complete: it gives the endpoint, the id semantics, the file-return behavior via schema, and how to retrieve the id. The only minor gap is not explicitly stating how id_by_customer is passed in the request, though the endpoint path implies it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only schema parameter, get_file, is fully described in the schema with enum-type behavior for e_invoice_type values, so the description need not repeat it. It adds useful context about id_by_customer as a UI counter, but that is path/id context rather than schema parameter detail. Baseline 3 applies because schema coverage is 100%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'get' and resource 'single receipt for a specified customer account by id_by_customer', and explicitly distinguishes itself from receipts_list by saying it fetches a single receipt. The endpoint line reinforces exactly what operation is invoked. This is enough for an agent to know what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use to fetch a single receipt whose id you already have' and 'To search or page through receipts, use receipts_list.' It also tells the agent how to obtain id_by_customer first via /receipts/get. That is strong when-to-use vs alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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; the response reports the total in rows.
Endpoint: POST /receipts/get
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | A limit of returned data. If no limit is given, the default will be 500. Also the maximum limit is 500. If specified, the field will be validated. | |
| order | No | Possible fields are: date amount invoicenumber (invoice_number) invoicingparty (counterparty) Allowed values are 'ASC' and 'DESC' Example: {"date": "ASC"} {"date": "ASC", "amount": "DESC"} | |
| offset | No | The offset for paging returned data. If no offset is given, the default will be 0. If specified, the field will be validated. | |
| date_to | No | The receipt's issuing date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All receipts with issuing date including and before given value will be returned. If specified, the field will be validated. An empty string is not considered a valid date. | |
| deleted | No | If true, only deleted receipts will be returned. If specified, the field will be validated. | |
| due_date | No | The receipt's issuing due date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All receipts with the same due date given value will be returned. If specified, the field will be validated. An empty string is not considered a valid due date. | |
| date_from | No | The receipt's issuing date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All receipts with issuing date including and after given value will be returned. If specified, the field will be validated. An empty string is not considered a valid date. | |
| counterparty | No | The counterparty of the receipt, i.e. the invoicing party for type 'inbound' or the recipient for type 'outbound' (e.g. 'Peter Maier'). If specified, the field will be validated. | |
| invoicenumber | No | The invoicenumber for the invoice. If specified, the receipts with the same invoicenumber will be retrieved. | |
| include_offers | No | If true, offers will be included. If specified, the field will be validated. | |
| list_direction | Yes | Can be either 'inbound' ("Eingangsbelege") or 'outbound' ("Ausgangsbelege"). | |
| payment_status | No | Can be either 'paid' ("bezahlt") or 'unpaid' ("unbezahlt"). If specified, the field will be validated. | |
| date_since_last_modified | No | A date and time in format 'YYYY-MM-DD HH:MM:SS' (e.g. '2017-04-26 13:45:00'). If only 'YYYY-MM-DD' is specified, the time defaults to '23:59:59'. All receipts whose date_updated value is later than the specified value will be returned. If specified, the field will be validated. An empty string is not considered a valid date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of receipts data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the description reinforces but doesn't contradict. It adds useful behavioral context: the response includes row count and array, the requirement of list_direction, and the POST endpoint. No contradictions found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a read-only note, then explains the purpose and usage. It's reasonably concise, though it includes some redundancy (repeating 'get receipts' and the endpoint). Still, every sentence contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 13 parameters and nested objects, the description covers the main use cases and points to the correct sibling. Since an output schema exists, the description doesn't need to detail return values. It's adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema documents all parameters thoroughly. The description adds a little extra by noting list_direction is required and that limit/offset are supported, but it doesn't go beyond the schema in any substantial way. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('get receipts') and resource, and clarifies it fetches receipt data for a customer account. It explicitly differentiates from receipts_get_by_id, so an agent can tell them apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use this tool (search by direction, date range, or payment status) and explicitly names the alternative (receipts_get_by_id) for fetching a single known receipt. This provides strong routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| confirmed_only | No | If true, only confirmed assignments will be returned. If specified, the field will be validated. | |
| receipt_id_by_customer | Yes | The id_by_customer of the receipt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of transactions data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description's 'READ-ONLY: Makes no changes' statement mostly restates structured metadata. It adds some context around the use case and directionality, but does not disclose additional behavioral traits like pagination, confirmation behavior, or error conditions beyond what annotations and schema already convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and mostly front-loaded with the read-only indicator and the core purpose. Some repetition exists between the title, the bolded heading, and the first sentence, but each paragraph adds a distinct element: safety, primary function, usage example, and alternative sibling. The endpoint line is a small bonus.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only 2 parameters, full schema coverage, a rich output schema, and strong annotations, the description is complete enough for an agent to select and invoke it correctly. It covers the use case, the source of a required parameter, the opposite-direction sibling, and confirms safety.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds practical value by explaining that `id_by_customer` can be obtained from `/receipts/get`, which is useful for locating the required parameter value. It also frames `receipt_id_by_customer` as the key identifier, reinforcing the schema without being redundant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'get all transactions assigned to a specific receipt' for a given customer receipt. It clearly distinguishes itself from the sibling tool `transactions_list_assigned_receipts` by naming it as the opposite direction. The scope is precise and an agent can distinguish this tool from sibling tools without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use it: to see which bank transactions are linked to a given receipt, e.g., checking whether an invoice has been matched to a payment. It also names the alternative for the opposite direction (`transactions_list_assigned_receipts`), and explains how to obtain `id_by_customer` via `/receipts/get method` first, which is actionable prerequisite guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| id_by_customer | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=true. The description adds that this is a WRITE operation that reverts prior state and is reversible, which is useful behavioral context beyond the annotations. It does not describe side effects on related transactions or repeated restores.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded but repetitive, restating the restore concept multiple times. The opening parenthetical mentioning 'un-confirm a posting' adds noise because it is not the focus of this tool and could confuse an agent selecting between siblings.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is reasonably complete for a simple restore operation: it names the target resource, the trigger, the prerequisite lookup, and the endpoint. It is weaker operationally because the key identifier `id_by_customer` is referenced in prose but absent from the structured input schema, leaving ambiguity about how the tool call should be constructed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero input-schema parameters, the baseline is 4. The description contributes meaningful parameter guidance by identifying `id_by_customer` as the restore key and explaining how to obtain it. The main gap is that the input schema does not actually expose `id_by_customer`, so the passing mechanism is only implied by the endpoint.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation: restore a marked-as-deleted receipt for a specific customer account using `id_by_customer`. It also distinguishes itself from the sibling `receipts_delete` by saying it brings back a receipt deleted with that tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit use case: use when a receipt was deleted via `receipts_delete`. It also provides the prerequisite of obtaining `id_by_customer` from the `/receipts/get` method. However, it does not explicitly say when not to use it or point to the correct sibling for the un-confirm-posting case mentioned in the first line.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | The receipt's issuing date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). If specified, the field will be validated. An empty string is not considered a valid date. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| file | Yes | The receipt file as real file upload or as base64 encoded string. Accepted file types are: application/pdf, text/xml, application/xml, image/jpeg, image/png, image/bmp, image/tiff | |
| type | Yes | Can be 'invoice inbound' ("Eingangsrechnung"), 'invoice outbound' ("Ausgangsrechnung"), 'credit inbound' ("Eingangsgutschrift § 14 UStG"), 'credit outbound' ("Ausgangsgutschrift § 14 UStG"). | |
| amount | No | The total amount of the receipt, can be negative to indicate a reversed payment (e.g. -12.30). If specified, the field will be validated. '0.00' is not considered a valid receipt amount. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| account | No | If the receipt shall directly be assigned to a payment account, you can specify its posting account number (e.g. '1200'). If specified, the account must exist as a payment account for the customer. '0' is not considered a valid account. | |
| currency | No | Has to be 'EUR' if specified. If specified, the field will be validated. An empty string is not considered a valid currency. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| vat_rate | No | The receipt's vat rate (e.g. 19.00 or 0) - may also be an empty string to indicate a non-available or multiple vat rates. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| file_name | No | The name of the file. NOTE: This is required for files sent as base64 encoded string and will be ignored for files sent as real upload. | |
| counterparty | No | The counterparty of the receipt, i.e. the invoicing party for type 'invoice inbound' or the recipient for type 'invoice outbound' (e.g. 'Peter Maier'). If specified, the field will be validated. An empty string is not considered a valid counterparty. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| date_delivery | No | The delivery date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). NOTE: Due to the DATEV compatibility, we cannot accept a delivery date that is after the receipt date! If specified, it will be validated. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| invoice_number | No | The invoice number (e.g. '1231XU23') with a maximum length of 60 characters - may also be an empty string. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| creditor_debtor | No | If the receipt shall directly be assigned to a creditor (for type 'invoice inbound') or debtor (for type 'invoice outbound') account, you can specify its posting account number (e.g. '70001'). If specified, creditors/debtors have to be activated for the customer, the creditor/debtor account must exist for the customer and it must be compatible with the specified receipt type. '0' is not considered a valid creditor/debtor. | |
| date_payment_due | No | The payment due date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). NOTE: This parameter will be ignored when you upload an e-invoice! | |
| payment_reference | No | The payment reference id. If specified correctly, the uploaded receipt will match with the corresponding transaction. Currently we support Amazon order id, PayPal transaction id and Stripe transaction id. NOTE: This parameter will be ignored when you upload an e-invoice! | |
| link_to_receipt_id_by_customer | No | Has to be a valid id_by_customer of another receipt. If specified, both receipts will be assigned to a transaction if one of them is assigned manually. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| filename | No | Internal filename after upload without extension |
| id_by_customer | No | blank |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses non-idempotency ('calling twice may create duplicates') and rate limiting ('max 10 requests per minute'), which are behavioral traits not fully covered by annotations alone. It also explains the processing via BuchhaltungsButler and the response filename, adding valuable context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description contains redundancy: 'Not idempotent' appears twice and 'Rate limited to 10 requests per minute' also appears twice. The inclusion of the 'Endpoint: POST /receipts/upload' line is unnecessary as it is not behaviorally relevant. While structured, the repetition prevents a higher score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 15 parameters and an output schema, the description covers the primary purpose, alternatives, rate limit, non-idempotency, and the response format (filename). The schema handles parameter details, so the description is sufficiently complete for an agent to decide when and how to invoke the tool. Minor gaps like e-invoice behavior are covered in the schema, so a 4 is justified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are already documented in the schema. The description does not add any parameter-specific semantics beyond what the schema provides; it only offers general notes about rate limiting and non-idempotency. Thus, the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Upload a receipt into the specified customer account' and clearly identifies the resource and action. It also differentiates from the sibling tool receipts_create by noting 'To record a receipt without a file, use receipts_create', making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it ('Use to send the actual receipt file') and when not to ('To record a receipt without a file, use receipts_create'). It also mentions the rate limit and non-idempotency, giving clear context for usage decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | Yes | The last day of the period the report is created for, in format 'YYYY-MM-DD' (e.g. '2026-03-31'). | |
| date_from | Yes | The first day of the period the report is created for, in format 'YYYY-MM-DD' (e.g. '2026-01-01'). |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| id_by_customer | No | The id_by_customer of the created report |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the call as a non-idempotent write. The description adds valuable context beyond the annotations: the operation runs asynchronously, returns an id instead of the report, and replaces a previously generated report. This gives the agent a clear model of the side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is noticeably repetitive: the 'new report may only be requested once the previous one has finished' constraint appears twice, and the async/returns-id idea is also echoed. The generic WRITE warning at the top duplicates the annotations content, making the whole description longer and less scannable than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The definition covers the async flow, response id, usage constraint (one at a time), and the sibling tool to fetch the result. With an output schema present, it does not need to explain the return shape. It is complete enough for an agent to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for both date_from and date_to, including format and examples. The description does not and need not add parameter details beyond what the schema provides, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Triggers the creation of a BWA report' and identifies the report type as 'Betriebswirtschaftliche Auswertung'. It clearly differentiates from the sibling read tool by noting this is 'Step one of two' and that reports_get_bwa is the follow-up.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use to request a BWA... Step one of two' and 'To read the finished report, call reports_get_bwa afterwards.' It also states that a new report may only be requested once the previous one has finished, providing an explicit call-ordering constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | The date the postings are taken into account by. Can be either 'date' ("Buchungsdatum") or 'date_delivery_else_date' ("Buchungs- und Leistungsdatum"). If specified, the field will be validated. | |
| date_to | Yes | The last day of the period the report is created for, in format 'YYYY-MM-DD' (e.g. '2026-03-31'). | |
| file_csv | No | If true, a csv file will be created for the report additionally. If specified, the field will be validated. | |
| file_pdf | No | If true, a pdf file will be created for the report additionally. If specified, the field will be validated. | |
| date_from | Yes | The first day of the period the report is created for, in format 'YYYY-MM-DD' (e.g. '2026-01-01'). | |
| archive_export | No | If true, a zip archive containing the csv file and the postingaccount ledgers ("Kontenblätter") will be created for the report additionally. If specified, the field will be validated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| id_by_customer | No | The id_by_customer of the created report |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds meaningful behavior beyond annotations: asynchronous background generation, response contains id_by_customer, one report at a time, and that a new request replaces the previous one. Annotations already indicate write and non-idempotent, and the description reinforces these; it does not fully explain how the caller knows generation has finished, but output schema likely covers response details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is padded with redundant statements: async behavior and the one-report-at-a-time constraint are each stated twice, and the opening write-header is generic and partly misleading. A tighter version would front-load 'create sums report' and keep the constraint once.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations cover idempotency/write semantics, the description is reasonably complete for an async create tool: it names the follow-up read call, the id returned, and the serialization constraint. It does not explain how to detect completion or what happens if a request is made while another is still running, which is a notable gap for an async workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter has a solid description (date_from/date_to formats, file_csv/file_pdf/archive_export booleans, base selection). The tool description does not need to repeat these; it adds no extra parameter-level meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it 'Triggers the creation of a sums report' and names the German 'Summen- und Saldenliste', with the sibling 'reports_get_sums' explicitly distinguished as the follow-up read step. However, the opening generic line 'Creates new records (receipts, transactions, postings, invoices, master data)' is boilerplate that inaccurately implies a broader record-creation tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage direction: 'Use to request a sums and balances report', 'Step one of two', and 'To read the finished report, call reports_get_sums afterwards'. It does not explicitly contrast with reports_create_bwa or other report variants, but the create-then-get flow is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| get_files | No | If true, the report's files will be included as base64 encoded strings. If specified, the field will be validated. | |
| report_id_by_customer | Yes | The id_by_customer of the report, as returned when the report was created |
Output Schema
| Name | Required | Description |
|---|---|---|
| files | No | Only contained if get_files has been specified. Provides the keys 'csv' and 'pdf', each holding the base64 encoded content of the report's file, or null if the file is not available – because it has not been requested when the report was created, because it is still being created or because it is not available anymore. |
| report | No | The report's data, containing the keys 'integrityError', 'standardChart', 'usedCostLocations', 'usedPostingaccountsNumbers', 'postingsRecordsCount', 'uncompletedPostingsCount', 'groups' and 'totals'. The groups hold their classes, which in turn hold their postingaccounts. Every group, class, postingaccount and total provides its amount as the unformatted value 'amountsSum'. |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: reports are generated asynchronously, the report is only available after generation finishes, and a new creation request replaces the previous report. It also notes that the endpoint returns nothing useful until generation has finished. This is strong added context, though it doesn't detail the exact response structure or error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear READ-ONLY banner, a bolded title, and short paragraphs. It front-loads the most important behavioral facts (read-only, async generation, replacement behavior) and includes the endpoint. It is slightly repetitive in places (e.g., 'Returns nothing useful until generation has finished' restates the async point), but overall every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (async generation, replacement semantics, two-step workflow), the description covers the essential context: when the report is available, what to do if it isn't ready, and the relationship to reports_create_bwa. The output schema exists, so return values don't need explanation. Minor gap: it doesn't explicitly state what happens if the report_id_by_customer is invalid or not found, but this is not critical for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (report_id_by_customer and get_files). The description adds a small amount of context by explaining that report_id_by_customer is the id returned at creation time, but it doesn't add significant meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a previously created BWA report, names the specific resource (BWA report), and explicitly distinguishes it from the creation step by calling it 'step two of two'. It also names the sibling tool reports_create_bwa, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use this tool to read a BWA that reports_create_bwa has finished generating, and provides clear guidance on when to wait and retry rather than requesting a new report. It also warns that creating a new report replaces the pending one, which is critical usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| get_files | No | If true, the report's files will be included as base64 encoded strings. If specified, the field will be validated. | |
| report_id_by_customer | Yes | The id_by_customer of the report, as returned when the report was created |
Output Schema
| Name | Required | Description |
|---|---|---|
| files | No | Only contained if get_files has been specified. Provides the keys 'csv', 'pdf' and 'csv_archive', each holding the base64 encoded content of the report's file, or null if the file is not available – because it has not been requested when the report was created, because it is still being created or because it is not available anymore. |
| report | No | The report's data, containing the keys 'integrityError', 'countPostingsWithDateVatEffectiveNotConsideredInReport' and 'sums'. The sums are keyed by postingaccount number, and every entry provides the 'postingaccount' itself as well as the unformatted values 'balanceBeforeDebit', 'balanceBeforeCredit', 'balanceBeforeAbsolute', 'balanceBeforeSide', 'sumPeriodDebit', 'sumPeriodCredit', 'balanceAfterDebit', 'balanceAfterCredit', 'balanceAfterAbsolute' and 'balanceAfterSide'. |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: reports are generated asynchronously, a report is only available after generation finishes, and creating a new report of the same type replaces the previous one. This explains statefulness and availability semantics that annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: the READ-ONLY warning and one-line summary come first, followed by the async caveat, usage instruction, sibling alternative, and endpoint. Every sentence earns its place, and the emoji/uppercase warning is immediately visible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only retrieval tool with a rich output schema, full parameter documentation, and annotations covering safety, the description is complete. It explains the async generation constraint, the replacement behavior, the two-step workflow, and the sibling alternative. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description adds context by explaining that `report_id_by_customer` is the id returned when the report was created, which reinforces the two-step workflow, but it does not add new parameter-level detail beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Returns'), a specific resource ('previously created sums report'), and explicitly distinguishes it from the sibling `reports_get_sums_ledger`. It also names the companion creation tool `reports_create_sums`, making the tool's role in a two-step workflow unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use this tool to read a sums report that `reports_create_sums` has finished generating, and calls it 'step two of two.' It also gives an exclusion: for individual bookings behind one posting account, use `reports_get_sums_ledger`. This is clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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 drill into one posting account of a finished sums report and see the individual entries behind its balance.
For the totals across all posting accounts, use reports_get_sums.
Requires a sums report created by reports_create_sums to have finished.
Endpoint: POST /reports/get/sums/ledger
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | The date the postings are taken into account by. Can be either 'date' ("Buchungsdatum") or 'date_delivery_else_date' ("Buchungs- und Leistungsdatum"). If specified, the field will be validated. | |
| date_to | Yes | The last day of the period the ledger is returned for, in format 'YYYY-MM-DD' (e.g. '2026-03-31'). | |
| date_from | Yes | The first day of the period the ledger is returned for, in format 'YYYY-MM-DD' (e.g. '2026-01-01'). | |
| postingaccount_number | Yes | The number of the postingaccount to return the ledger for |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
| report_sums_postingaccount_ledger | No | The ledger's data, containing the keys 'integrityError', 'postingaccount_number' and 'postingaccountLedger'. The 'postingaccount_number' is the number of the postingaccount the ledger has been returned for, whereas 'postingaccountLedger' is an array of the postingaccount's postings within the requested period, each one providing its date, posting text, counter postingaccount, amount, vat and the unformatted balance 'balanceAfterAbsolute' together with its side 'balanceAfterSide'. The array is empty if there are no postings in the requested period. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint and idempotentHint, and the description reinforces this with 'READ-ONLY' and 'Makes no changes to the accounting records'. It adds useful behavioral context beyond the annotations: the ledger is created on the fly andreports may take a while for posting accounts with many postings. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the read-only signal and purpose, but it repeats the title and the READ-ONLY info that annotations already provide. The two statements about report creation ('no report has to be created beforehand' and 'Requires a sums report...to have finished') are confusing and appear contradictory. It is organized, but not as tight as it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with four parameters, a complete output schema, and clear annotations, the description supplies the essential context: the prerequisite of a finished sums report, the alternative tool for totals, and a performance caveat. The main gap is the muddled phrasing around whether a report must already exist, which could confuse an agent deciding whether to call this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all parameters with formatsaisfais at 100% coverage, so the baseline is 3. The description adds meaningful guidance by explaining that valid postingaccount numbers come from reports_get_sums, both as keys of the 'sums' object and as entries' 'postingaccount_number'. It also clarifies that date_from and date_to define the ledger period, complementing the schema without repeating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns the postingaccount ledger (Kontenblatt) for one postingaccount over a requested period. It also frames it as a drill-down into a sums report, distinguishing it from reports_get_sums, which provides totals across all posting accounts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use this tool to drill into one posting account of a finished sums report and see individual entries behind its balance, and directs users to reports_get_sums for totals. It also states the prerequisite that a sums report created by reports_create_sums must have finished. However, the phrase 'no report has to be created beforehand' creates some ambiguity against that prerequisite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| transactions_to_receipts | Yes | list of receipts to transactions maximum of 50 element are allowed |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | is the request successful or faulty |
| transactions_to_receipts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a write operation (readOnlyHint=false), but the description adds valuable behavioral context: it links/unlinks records, is reversible, and does not book anything. It also clarifies batch behavior (one or many). This goes beyond what annotations provide and adds no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a summary line, usage guidance, and clear exclusions. Each sentence earns its place without redundancy. It is longer than minimal but not wasteful, and the key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a batch assignment tool, the description covers purpose, usage, alternatives, reversibility, and side effects (non-booking). The output schema exists, so return values are implicitly handled. With annotations already covering safety, nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the single parameter `transactions_to_receipts` with its nested structure and descriptions, achieving 100% coverage. The description adds minor context (e.g., 'a single record is an array of one') but does not substantially enhance parameter understanding beyond the schema, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool assigns receipts to transactions, and explicitly distinguishes it from the sibling `postings_assign_receipt_to_free` for attaching to postings. It uses a specific verb (assign) and resource (receipt â transaction), making the purpose unambiguous and differentiating it from similar tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: use it to match receipts to bank transactions, and when not to (attach to a posting) points to an alternative. It also mentions reversibility with `transactions_unassign_receipt` and clarifies that creating the link does not book anything, which informs the agent about the proper workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| transactions | Yes | list of transactions maximum of 50 transactions are allowed A transaction has the same fields like the /transactions/add endpoint has, same applies for error messages |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| success | Yes | is the request successful or faulty |
| transactions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=false and readOnlyHint=false, but the description adds critical specifics: calling twice creates duplicates, no duplicate detection, and no v1 endpoint to update/delete. It also clarifies that input must be an array (even a single record is an array of one). These details go well beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a warning about non-idempotency and then provides purpose and usage. It repeats 'Not idempotent' twice, which is slightly redundant, but the structure is otherwise efficient and organized (purpose, usage, precautions). It is not overly verbose and conveys all essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (array input, multiple optional fields) and the presence of a detailed schema and output schema, the description covers all necessary context: when to use, how to avoid duplicates, input format, and the lack of update/delete. It is complete for an agent to invoke correctly without additional ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for each field, so the baseline is 3. The description adds a valuable nuance: 'A single record is an array of one,' clarifying that even a single transaction must be wrapped in an array. It also reinforces the account must be a payment account, though the schema already states that. This modest addition justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool adds transactions to a payment account of a customer, with a specific use case (importing bank transactions from CSV or cash book). It distinguishes itself from read-only siblings like transactions_list by focusing on creation and explicitly mentions it takes one or many transactions. The verb 'add' and resource 'transaction' are precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this for importing transactions that no bank connection delivers, and advises checking transactions_list first for the date range to avoid duplicates. It also warns that there is no duplicate detection and no update/delete endpoint, guiding agents on when to call and what precautions to take. It doesn't explicitly name alternatives but gives clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of transaction data |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it is READ-ONLY, makes no changes to accounting records, and returns an array of transaction data. It also clarifies the semantics of id_by_customer, which is a meaningful behavioral detail beyond the schema. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise but contains redundancy: the title and the bolded line both say 'get transaction by id_by_customer', and the endpoint line is repeated in the description. The READ-ONLY note is useful and front-loaded, but the middle section could be tightened. It is not as crisp as it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters, an output schema, and strong annotations, the description covers the essential context: what it does, how to get the id, and when to use the sibling list tool. It does not describe the output structure, but the output schema exists, so that is not required. The only minor gap is not explaining why the endpoint is POST /transactions/get/id_by_customer, but that is not critical for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so the description cannot add parameter-level detail. The description does explain the key concept id_by_customer and how to obtain it, which is the closest thing to parameter semantics here. With 0 params, the baseline is 4, and the description earns it by explaining the lookup key's meaning and source.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: fetch a single bank transaction by id_by_customer. It also clarifies that id_by_customer is a per-customer counter, not a global database id, which helps distinguish the lookup key. However, the title and description contain redundant phrasing ('get transaction by id_by_customer') and the endpoint line is somewhat confusing, so it is not a perfect 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use transactions_list for searching or paging through transactions, and says to use this tool when you already have the id. It also tells the user how to obtain id_by_customer via the /transactions/get method first. This is clear usage guidance, though it does not enumerate all alternatives or explicitly say when not to use it beyond the list/search case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
Supports limit and offset; the response reports the total in rows. Ask for a bounded date range rather than the full history.
Endpoint: POST /transactions/get
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | A limit of returned data. If no limit is given, the default will be 500. Also the maximum limit is 500. If specified, the field will be validated. | |
| offset | No | The offset for paging returned data. If no offset is given, the default will be 0. If specified, the field will be validated. | |
| account | No | The account number of the account the transaction is stored to. If specified, the field will be validated. | |
| date_to | No | The transaction's booking date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All transaction with booking date including and before given value will be returned. An empty string is not considered a valid date. | |
| to_from | No | The payer/payee of the transaction. If specified, the field will be validated. | |
| date_from | No | The transaction's booking date in format 'YYYY-MM-DD' (e.g. '2017-04-26'). All transactions with booking date including and after given value will be returned. An empty string is not considered a valid date. | |
| id_by_customer_to | No | The id_by_customer as an integer. All transactions to given value will be returned. The transaction with the given value will NOT be returned! NOTE: By specifying this, the sort changes to id_by_customer ASC, even if you use this in combination with date params. If specified, the field will be validated. | |
| id_by_customer_from | No | The id_by_customer as an integer. All transactions after given value will be returned. The transaction with the given value will NOT be returned! NOTE: By specifying this, the sort changes to id_by_customer ASC, even if you use this in combination with date params. If specified, the field will be validated. | |
| date_since_last_modified | No | A date and time in format 'YYYY-MM-DD HH:MM:SS' (e.g. '2017-04-26 13:45:00'). If only 'YYYY-MM-DD' is specified, the time defaults to '23:59:59'. All transactions whose date_updated value is later than the specified value will be returned. If specified, the field will be validated. An empty string is not considered a valid date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of transactions data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description reinforces this with 'READ-ONLY: Fetches data. Makes no changes to the accounting records.' It adds pagination behavior (limit/offset, total in rows) and the recommendation to use bounded date ranges, which goes beyond the annotations and enriches the agent's understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured logically: a clear READ-ONLY tag, the action, usage, alternative, pagination note, and endpoint. While it is a bit longer than minimal, every sentence adds value and it is front-loaded with the key purpose. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description doesn't need to detail return fields, but it does mention the response includes rows and transaction data, which is helpful. It covers pagination, alternatives, and practical advice on date ranges. It is complete for an agent to call correctly, though it could note default sorting behaviors (which are in schema).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all parameters. The description mentions limit, offset, and date range but does not add new semantic meaning beyond what the schema already provides. Baseline 3 is appropriate when the schema carries the parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets transactions for a customer account, returns row count and transaction array, and explicitly differentiates from transactions_get_by_id. It uses specific verbs and resource names, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit usage context: 'Use to search bank transactions by account and date range' and 'To fetch one known transaction, use transactions_get_by_id.' It also advises bounding the date range, providing practical guidance on when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| confirmed_only | No | If true, only confirmed assignments will be returned. If specified, the field will be validated. | |
| transaction_id_by_customer | Yes | The id_by_customer of the transaction. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | No | An array of receipts data |
| rows | No | Number of returned rows |
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description repeats the read-only safety promise. It adds context about the endpoint and a prerequisite, but does not disclose deeper behavioral details such as auth requirements, rate limits, or response behavior beyond what the annotations and output schema already cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the read-only label and the key use case, and it is reasonably compact. There is some redundancy between the bolded repeated phrase and the following sentence, but overall it is well structured and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations, a full input schema, and an output schema, the description covers the important context an agent needs: the use case, the prerequisite for id_by_customer, the reverse-direction alternative, and the endpoint. Nothing essential for selecting or invoking the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description adds useful meaning for transaction_id_by_customer by explaining its source and how to retrieve it first. It does not add detail for confirmed_only, but that parameter is already well covered by the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'get all receipts assigned to a specific transaction' and clarifies the exact scope. It also names the reverse-direction sibling, receipts_list_assigned_transactions, so it is easy to distinguish from related transaction/receipt tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use the tool: to see which receipts are linked to a bank transaction, e.g. checking whether a payment has its invoice attached. It also tells the agent to use receipts_list_assigned_transactions for the opposite direction and explains how to obtain id_by_customer via the /transactions/get method first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| receipt_id_by_customer | Yes | The id_by_customer of the receipt to unassign. | |
| transaction_id_by_customer | Yes | The id_by_customer of the transaction. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | blank |
| success | Yes | Success boolean |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a non-destructive write (readOnlyHint=false, destructiveHint=false). The description adds valuable specifics: it is reversible, removes only the link, and neither the receipt nor the transaction is deleted. This goes beyond the annotation defaults and clarifies the exact effect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description has some redundancy: the opening line 'đĄ WRITE · links/unlinks records...' is generic and repeats the core idea of unassigning, and the bold heading duplicates the following sentence. However, the overall length is manageable and information is organized logically.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple unlink operation with an output schema present, the description covers the essential points: the use case, the effect (removes link, no deletion), and reversibility. It does not mention error conditions or prerequisites, but these are not critical for this straightforward action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters have clear descriptions ('The id_by_customer of the receipt to unassign', 'The id_by_customer of the transaction'). The tool description does not add additional parameter context, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'unassign' and the resource 'a specific receipt from a transaction', distinguishing it from the sibling transactions_assign_receipts. It explicitly says it removes only the link, which separates it from delete operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a specific use case: 'Use to undo a receipt-to-transaction match that was made in error.' This gives clear context, though it does not explicitly mention alternatives or when not to use. The context is sufficient for an agent to choose this over assign operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
86 tool updates
v1.1.2- Removed
accounts_add - Added
accounts_create - Removed
accounts_get - Added
accounts_list - Removed
comments_add - Added
comments_create - Removed
cost_locations_add - Added
cost_locations_create - Changed
cost_locations_delete1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Removed
cost_locations_get - Added
cost_locations_list - Changed
cost_locations_update1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Added
creditors_create - Added
creditors_list - Added
creditors_update - Added
debtors_create - Added
debtors_list - Added
debtors_update - Changed
invoices_create1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "file_name": { + "description": "Filename of the created invoice", + "type": "string" + }, + "id_by_customer": { + "description": "blank", + "type": "string" + }, + "invoicenumber": { + "description": "blank", + "type": "string" + }, + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
invoices_create_draft1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
invoices_create_e_invoice1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "file_name": { + "description": "Filename of the created invoice", + "type": "string" + }, + "id_by_customer": { + "description": "blank", + "type": "string" + }, + "invoicenumber": { + "description": "blank", + "type": "string" + }, + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Added
postingaccounts_create - Added
postingaccounts_list - Added
postingaccounts_update - Removed
postings_add_batch_free - Removed
postings_add_batch_receipts - Removed
postings_add_batch_transactions - Removed
postings_add_free - Removed
postings_add_receipt - Removed
postings_add_transaction - Added
postings_assign_receipt_to_free - Removed
postings_assign_receipt_to_free_posting - Changed
postings_cancel1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "Success message", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Added
postings_create_for_receipt - Added
postings_create_for_transaction - Added
postings_create_free - Removed
postings_get - Added
postings_list - Added
postings_unconfirm_for_receipt - Added
postings_unconfirm_for_transaction - Changed
postings_unconfirm_free1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "Success message", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Removed
postings_unconfirm_receipt - Removed
postings_unconfirm_transaction - Removed
receipts_add - Removed
receipts_addBatch - Removed
receipts_assigned_transactions_get - Added
receipts_create - Added
receipts_delete - Removed
receipts_delete_id_by_customer - Removed
receipts_get - Added
receipts_get_by_id - Removed
receipts_get_id_by_customer - Added
receipts_list - Added
receipts_list_assigned_transactions - Added
receipts_restore - Removed
receipts_restore_id_by_customer - Changed
receipts_upload1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "filename": { + "description": "Internal filename after upload without extension", + "type": "string" + }, + "id_by_customer": { + "description": "blank", + "type": "string" + }, + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
reports_create_bwa1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "id_by_customer": { + "description": "The id_by_customer of the created report", + "type": "string" + }, + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
reports_create_sums1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "id_by_customer": { + "description": "The id_by_customer of the created report", + "type": "string" + }, + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
reports_get_bwa1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "files": { + "description": "Only contained if get_files has been specified. Provides the keys 'csv' and 'pdf', each holding the base64 encoded content of the report's file, or null if the file is not available – because it has not been requested when the report was created, because it is still being created or because it is not available anymore.", + "type": "object" + }, + "message": { + "description": "blank", + "type": "string" + }, + "report": { + "description": "The report's data, containing the keys 'integrityError', 'standardChart', 'usedCostLocations', 'usedPostingaccountsNumbers', 'postingsRecordsCount', 'uncompletedPostingsCount', 'groups' and 'totals'.\n\nThe groups hold their classes, which in turn hold their postingaccounts. Every group, class, postingaccount and total provides its amount as the unformatted value 'amountsSum'.", + "type": "object" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
reports_get_sums1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "files": { + "description": "Only contained if get_files has been specified. Provides the keys 'csv', 'pdf' and 'csv_archive', each holding the base64 encoded content of the report's file, or null if the file is not available – because it has not been requested when the report was created, because it is still being created or because it is not available anymore.", + "type": "object" + }, + "message": { + "description": "blank", + "type": "string" + }, + "report": { + "description": "The report's data, containing the keys 'integrityError', 'countPostingsWithDateVatEffectiveNotConsideredInReport' and 'sums'.\n\nThe sums are keyed by postingaccount number, and every entry provides the 'postingaccount' itself as well as the unformatted values 'balanceBeforeDebit', 'balanceBeforeCredit', 'balanceBeforeAbsolute', 'balanceBeforeSide', 'sumPeriodDebit', 'sumPeriodCredit', 'balanceAfterDebit', 'balanceAfterCredit', 'balanceAfterAbsolute' and 'balanceAfterSide'.", + "type": "object" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
reports_get_sums_ledger1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "blank", + "type": "string" + }, + "report_sums_postingaccount_ledger": { + "description": "The ledger's data, containing the keys 'integrityError', 'postingaccount_number' and 'postingaccountLedger'.\n\nThe 'postingaccount_number' is the number of the postingaccount the ledger has been returned for, whereas 'postingaccountLedger' is an array of the postingaccount's postings within the requested period, each one providing its date, posting text, counter postingaccount, amount, vat and the unformatted balance 'balanceAfterAbsolute' together with its side 'balanceAfterSide'. The array is empty if there are no postings in the requested period.", + "type": "object" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Removed
settings_add_batch_creditors - Removed
settings_add_batch_debtors - Removed
settings_add_creditor - Removed
settings_add_debtor - Removed
settings_add_postingaccount - Removed
settings_get_creditors - Removed
settings_get_debtors - Removed
settings_get_postingaccounts - Removed
settings_update_creditor - Removed
settings_update_debtor - Removed
settings_update_postingaccount - Removed
transactions_add - Removed
transactions_addBatch - Removed
transactions_assign_batch_receipt - Removed
transactions_assign_receipt - Added
transactions_assign_receipts - Removed
transactions_assigned_receipts_get - Added
transactions_create - Removed
transactions_get - Added
transactions_get_by_id - Removed
transactions_get_id_by_customer - Added
transactions_list - Added
transactions_list_assigned_receipts - Changed
transactions_unassign_receipt1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "message": { + "description": "blank", + "type": "string" + }, + "success": { + "description": "Success boolean", + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
54 tool updates
v1.1.0- Changed
accounts_add1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
accounts_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
comments_add1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
cost_locations_add1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
cost_locations_delete1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
cost_locations_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
cost_locations_update1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
invoices_create1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
invoices_create_draft1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
invoices_create_e_invoice1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_add_batch_free1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_add_batch_receipts1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_add_batch_transactions1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_add_free1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_add_receipt1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_add_transaction1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_assign_receipt_to_free_posting1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_cancel1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_unconfirm_free1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_unconfirm_receipt1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
postings_unconfirm_transaction1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_add1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_addBatch1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_assigned_transactions_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_delete_id_by_customer1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_get_id_by_customer1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_restore_id_by_customer1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
receipts_upload1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
reports_create_bwa1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
reports_create_sums1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
reports_get_bwa1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
reports_get_sums1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
reports_get_sums_ledger1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_add_batch_creditors1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_add_batch_debtors1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_add_creditor1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_add_debtor1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_add_postingaccount1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_get_creditors1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_get_debtors1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_get_postingaccounts1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_update_creditor1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_update_debtor1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
settings_update_postingaccount1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_add1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_addBatch1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_assign_batch_receipt1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_assign_receipt1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_assigned_receipts_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_get1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_get_id_by_customer1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
- Changed
transactions_unassign_receipt1 field changed- removed
Input schema / properties / api_keyRemoved value: -{ - "description": "Optional. The BB customer api_key to act on. Defaults to the BB_API_KEY configured on the server â only set this to target a different customer.", - "type": "string" -}
14 tool updates
v1.0.2- Changed
invoices_create1 field changed- added
Input schema / properties / languageAdded value: +{ + "description": "The language for translatable invoice labels (e.g. headings, table headers, payment terms). Can be either 'de_DE' (\"Deutsch\", default) or 'en_US' (\"English\").\n\nIf omitted, German is used.", + "type": "string" +}
- Changed
invoices_create_draft1 field changed- added
Input schema / properties / languageAdded value: +{ + "description": "The language for translatable invoice labels (e.g. headings, table headers, payment terms). Can be either 'de_DE' (\"Deutsch\", default) or 'en_US' (\"English\").\n\nIf omitted, German is used.", + "type": "string" +}
- Changed
invoices_create_e_invoice1 field changed- added
Input schema / properties / languageAdded value: +{ + "description": "The language for translatable invoice labels (e.g. headings, table headers, payment terms). Can be either 'de_DE' (\"Deutsch\", default) or 'en_US' (\"English\").\n\nIf omitted, German is used.", + "type": "string" +}
- Changed
postings_add_free1 field changed- changed
Input schema / properties / vat / descriptionPrevious value: -"The vat rate of the posting.\n\nPossible vats:\n- 0_none ('keine Ust.')\n- 19_vat ('19% Ust.')\n- 7_vat ('7% Ust.')\n- 19_pre ('19% Vst.')\n- 7_pre ('7% Vst.')\n- 19_both_1 ('§13b 19% USt./VSt.')\n- 19_both_2 ('I.g.E. 19% USt./VSt.')\n- 7_both ('I.g.E. 7% USt./VSt.')\n- 19_both_1_no_pre ('§13b 19/16% USt.')\n- 19_both_2_no_pre ('i.g.E. 19/16% USt.')\n- 7_both_no_pre ('i.g.E. 7/5% USt.')\n- 19_pre_app ('19/16% Aufz. VSt.')\n- 7_pre_app ('7/5% Aufz. VSt.')\n- 19_both_app_1 ('§13b 19/16% USt./Aufz. VSt.')\n- 19_both_app_2 ('i.g.E. 19/16% USt./Aufz. VSt.')\n- 7_both_app ('i.g.E. 7/5% USt./Aufz. VSt.')"New value: +"The vat rate of the posting.\n\nPossible vats:\n- 0_none ('keine Ust.')\n- 19_vat ('19% Ust.')\n- 7_vat ('7% Ust.')\n- 19_pre ('19% Vst.')\n- 7_pre ('7% Vst.')\n- 19_both_1 ('§13b 19% USt./VSt.')\n- 19_both_506 ('§13b 19% USt./VSt. (EU §13b Abs. 1)')\n- 19_both_6506 ('§13b 19% USt. (EU §13b Abs. 1, ohne VSt.)')\n- 19_both_511 ('§13b 19% USt./VSt. (Drittland §13b Abs. 2 Nr. 1)')\n- 19_both_6511 ('§13b 19% USt. (Drittland §13b Abs. 2 Nr. 1, ohne VSt.)')\n- 19_both_6501 ('§13b 19/16% USt. (ohne VSt.)')\n- 19_both_2 ('I.g.E. 19% USt./VSt.')\n- 7_both ('I.g.E. 7% USt./VSt.')\n- 19_both_1_no_pre ('§13b 19/16% USt.')\n- 19_both_2_no_pre ('i.g.E. 19/16% USt.')\n- 7_both_no_pre ('i.g.E. 7/5% USt.')\n- 19_pre_app ('19/16% Aufz. VSt.')\n- 7_pre_app ('7/5% Aufz. VSt.')\n- 19_both_app_1 ('§13b 19/16% USt./Aufz. VSt.')\n- 19_both_app_506 ('§13b 19/16% USt./Aufz. VSt. (EU §13b Abs. 1)')\n- 19_both_app_511 ('§13b 19/16% USt./Aufz. VSt. (Drittland §13b Abs. 2 Nr. 1)')\n- 19_both_app_2 ('i.g.E. 19/16% USt./Aufz. VSt.')\n- 7_both_app ('i.g.E. 7/5% USt./Aufz. VSt.')"
- Changed
postings_add_receipt1 field changed- changed
Input schema / properties / vats / descriptionPrevious value: -"An array of vats.\n\nUsage:\n\"vats\" : ['vat of posting 1', 'vat of posting 2'].\n\nPossible vats:\n- 0_none ('keine Ust.')\n- 19_vat ('19% Ust.')\n- 7_vat ('7% Ust.')\n- 19_pre ('19% Vst.')\n- 7_pre ('7% Vst.')\n- 19_both_1 ('§13b 19% USt./VSt.')\n- 19_both_2 ('I.g.E. 19% USt./VSt.')\n- 7_both ('I.g.E. 7% USt./VSt.')\n- 19_both_1_no_pre ('§13b 19/16% USt.')\n- 19_both_2_no_pre ('i.g.E. 19/16% USt.')\n- 7_both_no_pre ('i.g.E. 7/5% USt.')\n- 19_pre_app ('19/16% Aufz. VSt.')\n- 7_pre_app ('7/5% Aufz. VSt.')\n- 19_both_app_1 ('§13b 19/16% USt./Aufz. VSt.')\n- 19_both_app_2 ('i.g.E. 19/16% USt./Aufz. VSt.')\n- 7_both_app ('i.g.E. 7/5% USt./Aufz. VSt.')"New value: +"An array of vats.\n\nUsage:\n\"vats\" : ['vat of posting 1', 'vat of posting 2'].\n\nPossible vats:\n- 0_none ('keine Ust.')\n- 19_vat ('19% Ust.')\n- 7_vat ('7% Ust.')\n- 19_pre ('19% Vst.')\n- 7_pre ('7% Vst.')\n- 19_both_1 ('§13b 19% USt./VSt.')\n- 19_both_506 ('§13b 19% USt./VSt. (EU §13b Abs. 1)')\n- 19_both_6506 ('§13b 19% USt. (EU §13b Abs. 1, ohne VSt.)')\n- 19_both_511 ('§13b 19% USt./VSt. (Drittland §13b Abs. 2 Nr. 1)')\n- 19_both_6511 ('§13b 19% USt. (Drittland §13b Abs. 2 Nr. 1, ohne VSt.)')\n- 19_both_6501 ('§13b 19/16% USt. (ohne VSt.)')\n- 19_both_2 ('I.g.E. 19% USt./VSt.')\n- 7_both ('I.g.E. 7% USt./VSt.')\n- 19_both_1_no_pre ('§13b 19/16% USt.')\n- 19_both_2_no_pre ('i.g.E. 19/16% USt.')\n- 7_both_no_pre ('i.g.E. 7/5% USt.')\n- 19_pre_app ('19/16% Aufz. VSt.')\n- 7_pre_app ('7/5% Aufz. VSt.')\n- 19_both_app_1 ('§13b 19/16% USt./Aufz. VSt.')\n- 19_both_app_506 ('§13b 19/16% USt./Aufz. VSt. (EU §13b Abs. 1)')\n- 19_both_app_511 ('§13b 19/16% USt./Aufz. VSt. (Drittland §13b Abs. 2 Nr. 1)')\n- 19_both_app_2 ('i.g.E. 19/16% USt./Aufz. VSt.')\n- 7_both_app ('i.g.E. 7/5% USt./Aufz. VSt.')"
- Changed
postings_add_transaction1 field changed- changed
Input schema / properties / vats / descriptionPrevious value: -"An array of vats.\n\nUsage:\n\"vats\" : ['vat of posting 1', 'vat of posting 2'].\n\nPossible vats:\n- 0_none ('keine Ust.')\n- 19_vat ('19% Ust.')\n- 7_vat ('7% Ust.')\n- 19_pre ('19% Vst.')\n- 7_pre ('7% Vst.')\n- 19_both_1 ('§13b 19% USt./VSt.')\n- 19_both_2 ('I.g.E. 19% USt./VSt.')\n- 7_both ('I.g.E. 7% USt./VSt.')\n- 19_both_1_no_pre ('§13b 19/16% USt.')\n- 19_both_2_no_pre ('i.g.E. 19/16% USt.')\n- 7_both_no_pre ('i.g.E. 7/5% USt.')\n- 19_pre_app ('19/16% Aufz. VSt.')\n- 7_pre_app ('7/5% Aufz. VSt.')\n- 19_both_app_1 ('§13b 19/16% USt./Aufz. VSt.')\n- 19_both_app_2 ('i.g.E. 19/16% USt./Aufz. VSt.')\n- 7_both_app ('i.g.E. 7/5% USt./Aufz. VSt.')"New value: +"An array of vats.\n\nUsage:\n\"vats\" : ['vat of posting 1', 'vat of posting 2'].\n\nPossible vats:\n- 0_none ('keine Ust.')\n- 19_vat ('19% Ust.')\n- 7_vat ('7% Ust.')\n- 19_pre ('19% Vst.')\n- 7_pre ('7% Vst.')\n- 19_both_1 ('§13b 19% USt./VSt.')\n- 19_both_506 ('§13b 19% USt./VSt. (EU §13b Abs. 1)')\n- 19_both_6506 ('§13b 19% USt. (EU §13b Abs. 1, ohne VSt.)')\n- 19_both_511 ('§13b 19% USt./VSt. (Drittland §13b Abs. 2 Nr. 1)')\n- 19_both_6511 ('§13b 19% USt. (Drittland §13b Abs. 2 Nr. 1, ohne VSt.)')\n- 19_both_6501 ('§13b 19/16% USt. (ohne VSt.)')\n- 19_both_2 ('I.g.E. 19% USt./VSt.')\n- 7_both ('I.g.E. 7% USt./VSt.')\n- 19_both_1_no_pre ('§13b 19/16% USt.')\n- 19_both_2_no_pre ('i.g.E. 19/16% USt.')\n- 7_both_no_pre ('i.g.E. 7/5% USt.')\n- 19_pre_app ('19/16% Aufz. VSt.')\n- 7_pre_app ('7/5% Aufz. VSt.')\n- 19_both_app_1 ('§13b 19/16% USt./Aufz. VSt.')\n- 19_both_app_506 ('§13b 19/16% USt./Aufz. VSt. (EU §13b Abs. 1)')\n- 19_both_app_511 ('§13b 19/16% USt./Aufz. VSt. (Drittland §13b Abs. 2 Nr. 1)')\n- 19_both_app_2 ('i.g.E. 19/16% USt./Aufz. VSt.')\n- 7_both_app ('i.g.E. 7/5% USt./Aufz. VSt.')"
- Added
postings_cancel - Changed
receipts_get1 field changed- added
Input schema / properties / date_since_last_modifiedAdded value: +{ + "description": "A date and time in format 'YYYY-MM-DD HH:MM:SS' (e.g. '2017-04-26 13:45:00'). If only 'YYYY-MM-DD' is specified, the time defaults to '23:59:59'. All receipts whose date_updated value is later than the specified value will be returned.\n\nIf specified, the field will be validated. An empty string is not considered a valid date.", + "type": "string" +}
- Added
reports_create_bwa - Added
reports_create_sums - Added
reports_get_bwa - Added
reports_get_sums - Added
reports_get_sums_ledger - Changed
transactions_get1 field changed- added
Input schema / properties / date_since_last_modifiedAdded value: +{ + "description": "A date and time in format 'YYYY-MM-DD HH:MM:SS' (e.g. '2017-04-26 13:45:00'). If only 'YYYY-MM-DD' is specified, the time defaults to '23:59:59'. All transactions whose date_updated value is later than the specified value will be returned.\n\nIf specified, the field will be validated. An empty string is not considered a valid date.", + "type": "string" +}
48 tool updates
v1.0.0- First observed
accounts_add - First observed
accounts_get - First observed
comments_add - First observed
cost_locations_add - First observed
cost_locations_delete - First observed
cost_locations_get - First observed
cost_locations_update - First observed
invoices_create - First observed
invoices_create_draft - First observed
invoices_create_e_invoice - First observed
postings_add_batch_free - First observed
postings_add_batch_receipts - First observed
postings_add_batch_transactions - First observed
postings_add_free - First observed
postings_add_receipt - First observed
postings_add_transaction - First observed
postings_assign_receipt_to_free_posting - First observed
postings_get - First observed
postings_unconfirm_free - First observed
postings_unconfirm_receipt - First observed
postings_unconfirm_transaction - First observed
receipts_add - First observed
receipts_addBatch - First observed
receipts_assigned_transactions_get - First observed
receipts_delete_id_by_customer - First observed
receipts_get - First observed
receipts_get_id_by_customer - First observed
receipts_restore_id_by_customer - First observed
receipts_upload - First observed
settings_add_batch_creditors - First observed
settings_add_batch_debtors - First observed
settings_add_creditor - First observed
settings_add_debtor - First observed
settings_add_postingaccount - First observed
settings_get_creditors - First observed
settings_get_debtors - First observed
settings_get_postingaccounts - First observed
settings_update_creditor - First observed
settings_update_debtor - First observed
settings_update_postingaccount - First observed
transactions_add - First observed
transactions_addBatch - First observed
transactions_assign_batch_receipt - First observed
transactions_assign_receipt - First observed
transactions_assigned_receipts_get - First observed
transactions_get - First observed
transactions_get_id_by_customer - First observed
transactions_unassign_receipt
TDQS
Scored across 46 tools
Most tools are clearly separated by resource (accounts, postings, receipts, transactions, reports) and action (list, create, update, delete, unconfirm). The main confusion risk is among the posting tools: postings_create_for_receipt, postings_create_for_transaction, postings_create_free, and postings_cancel/unconfirm variants all relate to postings, but their descriptions clarify the target (receipt vs transaction vs free). The three invoice creation tools (invoices_create, invoices_create_draft, invoices_create_e_invoice) are also distinct but could be confused without reading descriptions.
The naming convention is mostly consistent: resource_verb (e.g., postings_list, accounts_create, receipts_delete, creditors_update). However, there are deviations: reports_get_sums_ledger and reports_get_bwa use a different order (reports_get_*), and some names are verbose (postings_assign_receipt_to_free, transactions_list_assigned_receipts). The pattern is still predictable and readable.
46 tools is on the high side, but the server covers a broad accounting domain (master data, postings, receipts, transactions, invoices, reports, assignments). The count feels heavy but each tool addresses a distinct operation. It is borderline between well-scoped and over-scoped; the redundancy of unconfirm variants and multiple invoice creation tools inflates the count.
The tool surface covers the core accounting workflow well: master data CRUD (accounts, creditors, debtors, postingaccounts, cost_locations), receipt and transaction management, posting creation and reversal, report generation, and invoice creation. Notable gaps: no update/delete for accounts, no list/update/cancel for invoices, no read/update/delete for comments, and no delete for creditors/debtors/postingaccounts. These are acknowledged as v1 limitations, so agents can work around them but some workflows will dead-end.
Maintenance
Related MCP Connectors
Malaysian SME accounting, e-Invoice and payroll for your AI. 64 tools; writes are approved drafts.
- ManiloOAuthapp.ledgy.api
Log, query, and edit expenses, budgets, and accounts in Manilo (formerly Ledgy) from any MCP-compatible AI assistant.
QuickBooks Online in Claude and ChatGPT: 221 tools, full ledger, multi-company, Canada + US, FR/EN.
Taokeh is accounting software for Malaysian SMEs â double-entry books, LHDN e-Invoice (MyInvois), SST, and full statutory payroll â and this connector opens a company's live books to the AI its owner already uses. 59 tools. The reads answer real questions from the ledger: P&L and balance sheet with server-computed comparisons, cash position, A/R and A/P aging, per-channel marketplace sales, an 8-week cash-flow forecast, tax position, document search with e-Invoice standing, and a one-call daily brief. The writes are drafts only â expenses, invoices, bills, quotes, purchase orders, receipts, credit and debit notes, adjusting journals, bank-statement imports and bank-row suggestions â every figure re-checked by the server, every draft waiting for a human tap in Taokeh. The AI can also work the Shoebox: staff snap paper on free phone logins, and the connector lists the pile, reads each photo, and files the draft with the original attached â the server maps its own stored copy, so the document trail stays byte-perfect. One connection is bound to one company at consent; no tool takes a company argument. Migrating from another system? The same connector stages the chart of accounts, opening balances, contacts, products, historical documents and workspace settings onto the owner's own review screens. Bring your own AI subscription â no per-call fees.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables 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.76 npm4MIT
- AlicenseNot gradedqualityBmaintenanceIntegrates 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.36 npm6MIT
- AlicenseCqualityDmaintenanceProvides comprehensive AI-agnostic access to all Firefly III personal finance features via 66 tools, enabling natural language management of accounts, transactions, budgets, and more.666 npm23MIT
- AlicenseBqualityCmaintenanceEnables 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.236 npmMIT