# FEDEO MCP ## Listen und Pagination Alle datensatzbasierten MCP-Listen und Suchwerkzeuge unterstützen `limit` (ganze Zahl 1–100, Standard 25) und `offset` (ganze Zahl ab 0). Das Wiki behält Standard 50. Die statische Liste der Beleg-Steuertypen benötigt keine Pagination. Die Antwort behält `rows` und ergänzt: ```json {"pagination":{"limit":25,"offset":0,"hasMore":true,"nextOffset":25}} ``` Für die nächste Seite dieselben Filter und `limit` mit `offset = pagination.nextOffset` verwenden. Bei `hasMore = false` ist `nextOffset = null`. Die Sortierung enthält eine eindeutige ID als Tie-Breaker. Gleichzeitiges Anlegen, Archivieren oder Ändern sortierrelevanter Felder kann wie bei jeder Offset-Pagination Seiten verschieben; die Abfragen bilden keinen gemeinsamen Datenbanksnapshot. Auch `accounting.incoming_invoices.files.list` ist paginiert. Archivierte Einträge bleiben entsprechend der bisherigen MCP-Regel ausgeblendet. ## Ausgangsbeleg-Schemas `tools/list` beschreibt die Unterfelder von `rows`, `address` und `report` für Beleg-Erstellung und -Bearbeitung sowie Positionen und Report beim Finalisieren. Positionen verwenden `costCentre`, der Beleg selbst `costcentre`. `unit` ist die numerische Einheiten-ID. Preise werden numerisch übergeben. Reportwerte liefert der Aufrufer; MCP berechnet sie nicht. Zusätzliche modulspezifische Objektfelder bleiben zulässig. ## Stammdaten und Kostenstellen Die folgenden Namensräume besitzen jeweils `create`, `update` und `archive`: | Namensraum nach `masterdata.` | Anlegen: Pflichtfelder | Automatischer Nummernkreis | | --- | --- | --- | | `customers` | `name` | `customerNumber` | | `vendors` | `name` | `vendorNumber` | | `contacts` | `fullName` oder `firstName`/`lastName` | – | | `products` | `name`, `unit` | – | | `services` | `name` | – | | `cost_centres` | `name` | `number` | | `branches` | `name` | `number` | | `teams` | `name` | – | | `vehicles` | `name` | – | | `inventory_items` | `name` | `articleNumber` | Nummernfelder sind beim Anlegen optional; ohne Angabe wird der bestehende Mandanten-Nummernkreis verwendet. Dieser muss in FEDEO eingerichtet sein. Bereits belegte Nummern werden übersprungen; explizite doppelte Nummern werden abgewiesen, auch wenn der vorhandene Eintrag archiviert ist. `update` verlangt `id` und mindestens ein bearbeitbares Feld. Kostenstellen verwenden UUIDs, die übrigen Bereiche numerische IDs. Nur angegebene Felder werden geändert. Nullable Felder lassen sich mit `null` leeren, Arrays werden vollständig ersetzt. Die Unterfelder von `infoData` werden beim Update zusammengeführt. Systemfelder wie Mandant, ID beim Anlegen, Archivstatus und Änderungsautor sind nicht frei schreibbar. Beispiel zum Anlegen einer Kostenstelle: ```json {"name":"masterdata.cost_centres.create","arguments":{"name":"Werkstatt","description":"Kosten der Werkstatt","branch":3}} ``` Über `cost_centres.update` lassen sich `parentCostcentre`, `project`, `branch`, `vehicle`, `inventoryitem` und `profiles` pflegen. Eltern müssen zum aktiven Mandanten gehören und dürfen nicht archiviert sein; Selbstbezüge und neue Hierarchie-Zyklen werden abgewiesen. Die HTTP-Ressourcenroute und MCP verwenden denselben Hierarchieprüfer. Fremdschlüssel und bekannte Verknüpfungen in JSON-Feldern werden auf Mandantenzugehörigkeit und Verfügbarkeit geprüft. Globale Mengeneinheiten bleiben lesbar; es werden keine Schreibwerkzeuge für diese mandantenübergreifenden Daten registriert. Artikel- und Leistungsänderungen stoßen die bestehende Leistungspreisberechnung an. Bei zusammengesetzten Leistungen stammen Preise aus der Zusammensetzung; für eine manuelle Preisvorgabe die Leistung mit `priceUpdateLocked: true` sperren. Manuelle `sellingPrice`-Werte werden mit `sellingPriceComposed.total` synchronisiert. Schreibvorgänge einschließlich Nummernvergabe und Preisberechnung laufen in einer Transaktion. Historieneinträge werden über den vorhandenen History-Service erstellt; für Niederlassungen und Teams unterstützt dieser derzeit keine entitätsbezogene Historie. Die Änderungsfelder enthalten auch dort den ausführenden Benutzer und Zeitpunkt. Archivieren liefert `{ "id": ..., "success": true, "action": "archived" }`; der archivierte Datensatz wird entsprechend der MCP-Regel nicht zurückgegeben. Zusätzlich verfügbar: `masterdata.customers.search` sowie `get` für Kontakte, Niederlassungen, Teams und Fahrzeuge. Die vorhandene Kundensuche unter `organisation.customers.search` bleibt erhalten. ### Berechtigungen Schreibwerkzeuge benötigen `masterdata..write`, lesende Werkzeuge `.read`. Die neuen Schreibrechte sind in den Bootstrap-Administratorrechten enthalten. Bestehende Nicht-Administratorrollen erhalten nicht automatisch Schreibzugriff; ihnen müssen die gewünschten Rechte ausdrücklich zugewiesen werden. Globale Administratoren verwenden die bestehende Admin-Ausnahme. ### Verifikation Die MCP-Tests prüfen unter anderem seitenweisen Abruf, Tenant-Filter in den erzeugten SQL-Abfragen, Create/Update/Archive, unbekannte Systemfelder, Fremdmandanten-Verknüpfungen, Kostenstellen-Zyklen, Nummernkollisionen, Transaktions-Rollback und die Preisneuberechnung. Die Datenbanktests verwenden isolierte Fixtures bzw. den Drizzle-Proxy; sie schreiben keine produktiven Daten.