From a584cf28647808032bc00cb93a51591e9b4a3af0 Mon Sep 17 00:00:00 2001 From: Matteo Date: Sat, 23 May 2026 14:09:07 +0200 Subject: [PATCH] datev: rewrite adapter against official OpenAPI specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous adapter was inferred from third-party docs and was wrong on every load-bearing field. Replaced with values extracted directly from DATEV's official OpenAPI specs at developer.datev.de/mediator/apis. Adapter changes (packages/backend/src/adapters/de/datev.json): - Auth URLs: login.datev.de/openid/authorize + api.datev.de/token (was login.datev.de/connect/{authorize,token} — non-existent paths). - Scopes: datev:accounting:clients accounting:clients:read accounting:documents (was openid offline_access accounting:documents:read/write — wrong namespacing). - X-DATEV-Client-Id: auto-injected on every call via connector.headers (was missing — required by every DATEV endpoint per spec). - Tools: 6 read tools wired to real endpoints across accounting-clients v2 and accounting-documents v2. Dropped two invented tools that don't exist on the API (datev_list_documents, datev_get_document — the documents product is upload-only). Added datev_get_duo_version and the documents product's own client listing. - Upload tools (POST/PUT/stapled) intentionally excluded: require binary multipart, REST engine still serializes form-data with String(v). Docs (content/guides/{en,de,it}/datev-to-mcp.mdx): rewritten to match the corrected adapter + document sandbox switching procedure and the DATEV partner / production-approval requirement. All 2209 catalog assertions pass. --- content/guides/de/datev-to-mcp.mdx | 132 ++++++++++++++++--- content/guides/en/datev-to-mcp.mdx | 134 +++++++++++++++++--- content/guides/it/datev-to-mcp.mdx | 133 +++++++++++++++++-- packages/backend/src/adapters/de/datev.json | 128 ++++++++++++------- 4 files changed, 432 insertions(+), 95 deletions(-) diff --git a/content/guides/de/datev-to-mcp.mdx b/content/guides/de/datev-to-mcp.mdx index 7a3f110..49cb08c 100644 --- a/content/guides/de/datev-to-mcp.mdx +++ b/content/guides/de/datev-to-mcp.mdx @@ -1,6 +1,6 @@ --- -title: "DATEV mit KI-Agenten via MCP verbinden — KI für die Buchhaltung" -description: "DATEV Buchhaltung über MCP mit KI-Agenten verbinden. Mandanten, Belege und Lohndaten per natürlicher Sprache abrufen. Der erste DATEV MCP Server." +title: "DATEV Online APIs an MCP anbinden — KI-Agenten für die Buchhaltung" +description: "Verbinden Sie die offiziellen DATEV Online APIs (accounting-clients + accounting-documents) mit jedem MCP-kompatiblen KI-Agenten. OIDC Authorization Code + PKCE gegen login.datev.de, gebunden an ein echtes DATEV-Konto." category: "connectors" keyword: "DATEV MCP Server, DATEV KI, DATEV mit Claude, DATEV ChatGPT, DATEV Schnittstelle KI, Steuerberater KI" publishedAt: "2026-03-15" @@ -9,30 +9,130 @@ adapterSlug: "datev" ## DATEV mit KI-Agenten verbinden -DATEV ist die dominierende Buchhaltungs- und Steuersoftware in Deutschland — genutzt von fast jedem Steuerberater und Tausenden von Unternehmen. Trotz seiner Marktdominanz gab es bisher keinen MCP-Server für DATEV. +DATEV ist die marktbeherrschende Buchhaltungs- und Steuersoftware in Deutschland — genutzt von praktisch jedem Steuerberater. Dieser Connector kapselt die offiziellen **DATEV Online APIs**, damit ein MCP-kompatibler KI-Agent (Claude, ChatGPT, Gemini, Copilot, Cursor) Ihre Mandanten und DATEV-Unternehmen-online-Metadaten auslesen kann. -Mit AnythingMCP verbinden Sie die offiziellen DATEV Online APIs mit jedem MCP-kompatiblen KI-Agenten (Claude, ChatGPT, Gemini usw.). +> **Bitte vorher lesen.** Die DATEV Online APIs sind **keine Plug-and-Play-Schnittstelle**. Sie benötigen (a) eine App im DATEV-Entwicklerportal, (b) ein Abonnement pro API-Produkt, (c) einen echten DATEV-Konto-Benutzer mit SmartLogin/SmartCard und (d) eine DATEV-Production-Approval-Freigabe, um die Sandbox zu verlassen. -## Schnelleinrichtung +## Aktueller Funktionsumfang + +Alle Werte unten stammen aus den offiziellen OpenAPI-Specs unter `https://developer.datev.de/mediator/apis//document`. + +| Tool | API-Produkt | Endpoint | Scope | +|------|-------------|----------|-------| +| `datev_list_clients` | accounting-clients v2 | `GET /clients` | `datev:accounting:clients` | +| `datev_get_client` | accounting-clients v2 | `GET /clients/{id}` | `datev:accounting:clients` | +| `datev_documents_list_clients` | accounting-documents v2 | `GET /clients` | `accounting:clients:read` | +| `datev_get_documents_client` | accounting-documents v2 | `GET /clients/{id}` | `accounting:clients:read` | +| `datev_list_document_types` | accounting-documents v2 | `GET /clients/{id}/document-types` | `accounting:documents` | +| `datev_get_duo_version` | accounting-documents v2 | `GET /clients/{id}/duo-version` | `accounting:clients:read` | + +### Aktuell **nicht** abgedeckt + +Drei Upload-Endpoints existieren auf `accounting-documents v2`, benötigen aber `multipart/form-data` mit einem binären Datei-Part. Die REST-Engine serialisiert Form-Data-Felder derzeit per `String(v)`, was binäre PDFs/Bilder zerstört. Sobald die Engine `Buffer`/Base64 akzeptiert, kommen sie dazu: + +- `POST /clients/{id}/documents` — auto-vergebene Dokument-ID +- `PUT /clients/{id}/documents/{guid}` — Aufrufer-vergebene RFC4122-GUID +- `PUT /clients/{id}/documents/stapled` — mehrere Dokumente in einem Request + +Außerhalb des Scopes: `accounting:dataexchange`, `accounting:dxso-jobs`, `accounting:extf-files`, HR/Lohn (`hr-documents`, `hr-imports`, `hr-payrollreports`, `eau-api`), DMS, addressee, cashregister und der next-gen `datev_idp_next` IdP (`signin.datev.de/datevam/...`). + +## Voraussetzungen — Checkliste im DATEV-Portal + +1. Registrierung im [DATEV-Entwicklerportal](https://developer.datev.de). Organisation beitreten oder erstellen. +2. App anlegen: + - **Authorization Flow**: *OpenID Connect Authorization Code Flow* (nicht Hybrid) + - **Client Type**: *Confidential* (liefert 2-Jahres rolling Refresh-Token; erforderlich für unbeaufsichtigten Betrieb) + - **Redirect-URLs**: `https:///api/mcp-oauth/callback` (Pfad muss exakt passen — `http://localhost` nur auf Sandbox) +3. Abonnement für *accounting-clients v2* **und** *accounting-documents v2* auf der [DATEV-Programm-Seite](https://developer.datev.de/en/products/988700e4-e0c5-40bf-814b-cd7327dad67a). Beide teilen sich dasselbe OAuth-Abonnement. +4. `Client ID` und `Client Secret` notieren. Apps starten in der **Sandbox**; für `*.api.datev.de` (Produktion) ist DATEVs Production-Approval-Review erforderlich. +5. DATEV-Konto-Benutzer mit SmartLogin oder SmartCard/mIDentity. `client_credentials` wird **nicht** unterstützt. + +## Installation ```bash git clone https://github.com/HelpCode-ai/anythingmcp.git cd anythingmcp && docker compose up -d ``` -Registrieren Sie sich im [DATEV Developer Portal](https://developer.datev.de), erstellen Sie eine Anwendung und importieren Sie den DATEV-Adapter. +`http://localhost:3000/connectors/store` öffnen, DATEV-Adapter installieren und konfigurieren: + +| Env-Variable | Wert | +|--------------|------| +| `DATEV_CLIENT_ID` | aus dem DATEV-Portal | +| `DATEV_CLIENT_SECRET` | aus dem DATEV-Portal | + +Der Connector liefert **standardmäßig Produktions-URLs**: +- Authorization: `https://login.datev.de/openid/authorize` +- Token: `https://api.datev.de/token` +- API-Bases: `https://accounting-clients.api.datev.de/platform/v2` + `https://accounting-documents.api.datev.de/platform/v2` + +Er injiziert außerdem auf jeder Anfrage automatisch `X-DATEV-Client-Id: ` (das `client_id`-apiKey-Schema ist **bei jedem DATEV-Endpoint** zusätzlich zum Bearer-Token erforderlich). + +## Wechsel zur Sandbox + +Neue DATEV-Apps starten in der Sandbox, bis die Production-Approval erteilt ist. Um den Connector auf die Sandbox zu zeigen, **nach der Installation** den gespeicherten `authConfig` bearbeiten: + +| Feld | Sandbox-Wert | +|------|--------------| +| `authorizationUrl` | `https://login.datev.de/openidsandbox/authorize` | +| `tokenUrl` | `https://sandbox-api.datev.de/token` | + +Und in jedem `endpointMapping.path` der Tools `platform` durch `platform-sandbox` ersetzen: +- `https://accounting-clients.api.datev.de/platform-sandbox/v2/...` +- `https://accounting-documents.api.datev.de/platform-sandbox/v2/...` + +Eine spätere Iteration kann das über eine `DATEV_ENV=sandbox`-Env-Variable abkürzen. + +## Einmaliger OAuth-Ablauf + +Nach der Installation Authorization Code + PKCE anstoßen: + +```bash +curl -X POST http://localhost:4000/api/connectors//oauth/authorize \ + -H "Authorization: Bearer " +``` + +Die Antwort enthält eine `authorizationUrl`. Im Browser öffnen, mit DATEV-Konto anmelden, die Scopes freigeben: + +``` +datev:accounting:clients +accounting:clients:read +accounting:documents +``` + +(Hinweis: `openid` ist der Issuer-Name des aktuellen `datev_openid` Flows, **kein** Scope. Das OpenAPI-Security-Schema enthält ihn nicht.) + +DATEV leitet zurück auf `/api/mcp-oauth/callback`; die Plattform speichert ein verschlüsseltes Refresh-Token in `authConfig`. Ab dann erneuert die Engine das Access-Token still 5 Minuten vor Ablauf. Confidential Clients bekommen ein 2-Jahres rolling Refresh-Token. + +## Tools verwenden + +Jedes Mandanten-spezifische Tool erwartet einen `clientId`-Parameter — die **Mandant-UUID** (RFC4122 `8-4-4-4-12`), **nicht zu verwechseln mit Ihrem OAuth-`DATEV_CLIENT_ID`**. Zuerst `datev_list_clients` aufrufen, um die UUIDs zu erhalten. + +```text +Agent: Liste meine DATEV-Mandanten +→ datev_list_clients +← [{ id: "a0b1c2d3-…", consultant_number: 12345, client_number: 1, name: "Müller GmbH" }, …] + +Agent: Welche Belegtypen sind für Müller GmbH auf DUO konfiguriert? +→ datev_list_document_types(clientId: "a0b1c2d3-…") + +Agent: Welche Dateiformate akzeptiert DUO für Müller GmbH? +→ datev_get_duo_version(clientId: "a0b1c2d3-…") +``` + +## Hinweis zu zwei "list_clients"-Tools + +`datev_list_clients` ruft accounting-clients v2 — die kanonische Mandantenliste, für die Ihr Benutzer freigeschaltet ist. + +`datev_documents_list_clients` ruft accounting-documents v2 — nur die Teilmenge dieser Mandanten mit **aktivem DATEV Unternehmen online**-Abo (also bereit für Beleg-Upload). Diese vor einem Upload nutzen, um zu wissen, welche Mandanten ihn annehmen. -## Verfügbare Tools +## CSV / EXTF — die pragmatische Alternative für KMU -| Tool | Beschreibung | -|------|-------------| -| `datev_list_clients` | Mandanten auflisten | -| `datev_list_documents` | Belege eines Mandanten auflisten | -| `datev_get_document` | Belegdetails per GUID abrufen | -| `datev_upload_document` | Rechnungen/Belege in DATEV Belege online hochladen | +Ohne DATEV-Partnervertrag/Production-Approval ist die Online-API kein Weg. Der Standard-Integrationspfad für KMU ist die Erzeugung einer **DATEV-ASCII / EXTF Buchungsstapel-CSV** (`EXTF_Buchungsstapel.csv`, Formatspezifikation 700/810), die der Steuerberater in *Rechnungswesen pro* importiert. Kein OAuth, kein Portal-Abo, keine Production-Approval. Ein dedizierter EXTF-Generator-Adapter ist geplant; bis dahin ist das Ruby-Gem [ledermann/datev](https://github.com/ledermann/datev) die Referenzimplementierung des Formats. -## KI-Anwendungsfälle +## Anwendungsfälle - **"Liste alle meine DATEV-Mandanten"** -- **"Zeige die Belege dieses Monats für Mandant Müller"** -- **"Lade diese Rechnung in DATEV Belege online hoch"** +- **"Welche meiner Mandanten haben ein DUO-Abo?"** +- **"Welche Belegtypen sind für Mandant Müller konfiguriert?"** +- **"Welche Dateiformate akzeptiert DUO für Mandant a0b1c2d3-…?"** diff --git a/content/guides/en/datev-to-mcp.mdx b/content/guides/en/datev-to-mcp.mdx index 565bf36..2712895 100644 --- a/content/guides/en/datev-to-mcp.mdx +++ b/content/guides/en/datev-to-mcp.mdx @@ -1,6 +1,6 @@ --- title: "How to Connect DATEV to MCP for AI-Powered Accounting" -description: "Connect DATEV accounting to MCP. Access clients, documents, payroll data, and HR reporting with AI agents. The first DATEV MCP integration." +description: "Connect DATEV's Online APIs (accounting-clients + accounting-documents) to any MCP-compatible AI agent. OIDC Authorization Code + PKCE against login.datev.de, bound to a real DATEV-Konto." category: "connectors" keyword: "DATEV MCP Server, DATEV API AI, DATEV mit Claude, DATEV ChatGPT, DATEV Schnittstelle KI" publishedAt: "2026-03-15" @@ -9,36 +9,130 @@ adapterSlug: "datev" ## DATEV with AI Agents via MCP -DATEV is the dominant accounting and tax software platform in Germany, used by nearly every tax consultant (Steuerberater) and thousands of businesses. Despite its market dominance, there has been no MCP server for DATEV — until now. +DATEV is the dominant accounting and tax software platform in Germany, used by virtually every tax consultant (Steuerberater). This connector wraps DATEV's official **Online APIs** so an MCP-compatible AI agent (Claude, ChatGPT, Gemini, Copilot, Cursor) can read your Mandanten and DATEV Unternehmen online (DUO) metadata. -With AnythingMCP, you can connect DATEV's official Online APIs to any MCP-compatible AI agent (Claude, ChatGPT, Gemini, etc.). +> **Read this first.** DATEV's Online APIs are **not plug-and-play** like a public REST API. They require (a) a DATEV-Entwicklerportal app, (b) a subscription per API product, (c) a real DATEV-Konto user who logs in via SmartLogin / SmartCard, and (d) a DATEV production-approval review before you can leave sandbox. -## Quick Setup +## What this connector covers today + +All values below were extracted from the official OpenAPI specs at `https://developer.datev.de/mediator/apis//document`. + +| Tool | API product | Endpoint | Scope | +|------|-------------|----------|-------| +| `datev_list_clients` | accounting-clients v2 | `GET /clients` | `datev:accounting:clients` | +| `datev_get_client` | accounting-clients v2 | `GET /clients/{id}` | `datev:accounting:clients` | +| `datev_documents_list_clients` | accounting-documents v2 | `GET /clients` | `accounting:clients:read` | +| `datev_get_documents_client` | accounting-documents v2 | `GET /clients/{id}` | `accounting:clients:read` | +| `datev_list_document_types` | accounting-documents v2 | `GET /clients/{id}/document-types` | `accounting:documents` | +| `datev_get_duo_version` | accounting-documents v2 | `GET /clients/{id}/duo-version` | `accounting:clients:read` | + +### What is *not* covered (yet) + +Three upload endpoints exist on `accounting-documents v2` but require `multipart/form-data` with a binary file part. The REST engine currently serializes form-data field values via `String(v)`, which corrupts binary PDFs/images. They land once the engine accepts `Buffer`/base64 in form-data values. + +- `POST /clients/{id}/documents` — auto-assigned document ID +- `PUT /clients/{id}/documents/{guid}` — caller-assigned RFC4122 GUID +- `PUT /clients/{id}/documents/stapled` — multiple documents in one request + +Out of scope for this iteration: `accounting:dataexchange`, `accounting:dxso-jobs`, `accounting:extf-files`, HR/Lohn (`hr-documents`, `hr-imports`, `hr-payrollreports`, `eau-api`), DMS, addressee, cashregister, and the next-gen `datev_idp_next` IdP (`signin.datev.de/datevam/...`). + +## Prerequisites — DATEV portal checklist + +1. Register at the [DATEV-Entwicklerportal](https://developer.datev.de). Join or create an organization. +2. Create an app: + - **Authorization Flow**: *OpenID Connect Authorization Code Flow* (not Hybrid) + - **Client Type**: *Confidential* (gives 2-year rolling refresh tokens; required for unattended operation) + - **Redirect URLs**: `https:///api/mcp-oauth/callback` (path must match exactly — `http://localhost` is only allowed on sandbox) +3. Subscribe to *accounting-clients v2* **and** *accounting-documents v2* on the [DATEV program page](https://developer.datev.de/en/products/988700e4-e0c5-40bf-814b-cd7327dad67a). Both ride on the same OAuth subscription. +4. Note the `Client ID` and `Client Secret`. Apps start on **sandbox**; to call `*.api.datev.de` (production) you must go through DATEV's production-approval review. +5. Have a DATEV-Konto user with SmartLogin or SmartCard/mIDentity. `client_credentials` is **not** supported. + +## Install ```bash git clone https://github.com/HelpCode-ai/anythingmcp.git cd anythingmcp && docker compose up -d ``` -Open `http://localhost:3000/connectors/store`, import the DATEV adapter, and configure your OAuth 2.0 credentials from the [DATEV Developer Portal](https://developer.datev.de). +Open `http://localhost:3000/connectors/store`, install the DATEV adapter, and supply: + +| Env var | Value | +|---------|-------| +| `DATEV_CLIENT_ID` | from the DATEV portal | +| `DATEV_CLIENT_SECRET` | from the DATEV portal | + +The connector ships **production URLs by default**: +- Authorization: `https://login.datev.de/openid/authorize` +- Token: `https://api.datev.de/token` +- API bases: `https://accounting-clients.api.datev.de/platform/v2` + `https://accounting-documents.api.datev.de/platform/v2` + +It also auto-injects `X-DATEV-Client-Id: ` on every call (the `client_id` apiKey scheme is **required** by every DATEV endpoint alongside the Bearer token). + +## Switching to sandbox + +New DATEV apps default to sandbox until production approval. To point the connector at the sandbox, **after install** edit the connector's stored `authConfig`: + +| Field | Sandbox value | +|-------|---------------| +| `authorizationUrl` | `https://login.datev.de/openidsandbox/authorize` | +| `tokenUrl` | `https://sandbox-api.datev.de/token` | + +And in each tool's `endpointMapping.path`, replace `platform` with `platform-sandbox`: +- `https://accounting-clients.api.datev.de/platform-sandbox/v2/...` +- `https://accounting-documents.api.datev.de/platform-sandbox/v2/...` + +A future iteration may surface this via a `DATEV_ENV=sandbox` env var switch. + +## One-time OAuth dance + +After install, trigger Authorization Code + PKCE: + +```bash +curl -X POST http://localhost:4000/api/connectors//oauth/authorize \ + -H "Authorization: Bearer " +``` + +The response contains an `authorizationUrl`. Open it in a browser, log in with your DATEV-Konto, approve the scopes: + +``` +datev:accounting:clients +accounting:clients:read +accounting:documents +``` + +(Note: `openid` is the issuer name on the current `datev_openid` flow, **not** a scope. The OpenAPI security scheme does not include it.) + +DATEV redirects back to `/api/mcp-oauth/callback`; the platform stores an encrypted refresh token in `authConfig`. From here on the engine refreshes the access token silently 5 minutes before expiry. Confidential clients get a 2-year rolling refresh token. + +## Using the tools + +Every per-client tool takes a `clientId` parameter — this is the **Mandant UUID** (RFC4122 `8-4-4-4-12`), **distinct from your OAuth `DATEV_CLIENT_ID`**. Call `datev_list_clients` first to find the UUIDs your DATEV-Konto user can access. + +```text +agent: List my DATEV Mandanten +→ datev_list_clients +← [{ id: "a0b1c2d3-…", consultant_number: 12345, client_number: 1, name: "Müller GmbH" }, …] + +agent: What document types are configured for Müller GmbH on DUO? +→ datev_list_document_types(clientId: "a0b1c2d3-…") + +agent: What file formats does DUO accept for Müller GmbH? +→ datev_get_duo_version(clientId: "a0b1c2d3-…") +``` + +## Note on two "list_clients" tools -## Available Tools +`datev_list_clients` calls accounting-clients v2 — the canonical master list of every Mandant your user is provisioned for. -| Tool | Description | -|------|-------------| -| `datev_list_clients` | List accounting clients | -| `datev_list_documents` | List accounting documents for a client | -| `datev_get_document` | Get document details by GUID | -| `datev_upload_document` | Upload invoices/receipts to DATEV Belege online | +`datev_documents_list_clients` calls accounting-documents v2 — only the subset of those Mandanten that have an **active DATEV Unternehmen online** subscription (i.e. can receive document uploads). Use this one when preparing an upload to know which Mandanten will accept it. -## Prerequisites +## CSV / EXTF — the pragmatic alternative for SMBs -1. Register at the [DATEV Developer Portal](https://developer.datev.de) -2. Create an application to get OAuth 2.0 credentials -3. Your clients must be on DATEV Unternehmen online +If you don't have a DATEV partner contract / production approval, the Online API isn't an option. The standard SMB integration target is to **generate a DATEV-ASCII / EXTF Buchungsstapel CSV** (`EXTF_Buchungsstapel.csv`, format spec 700/810) and have the Steuerberater import it into *Rechnungswesen pro*. No OAuth, no portal subscription, no production approval. A dedicated EXTF-generator adapter is on the roadmap; in the meantime the [ledermann/datev](https://github.com/ledermann/datev) Ruby gem is the reference format implementation. -## Use Cases +## Use cases -- **"List all accounting clients"** -- **"Show documents uploaded this month for client 12345"** -- **"Upload this invoice to DATEV Belege online"** +- **"List all my DATEV Mandanten"** +- **"Which of my Mandanten have DUO subscriptions?"** +- **"What document types are configured for Mandant Müller?"** +- **"What file formats does DUO accept for client a0b1c2d3-…?"** diff --git a/content/guides/it/datev-to-mcp.mdx b/content/guides/it/datev-to-mcp.mdx index f54c132..60204ec 100644 --- a/content/guides/it/datev-to-mcp.mdx +++ b/content/guides/it/datev-to-mcp.mdx @@ -1,27 +1,138 @@ --- -title: "Come collegare DATEV a MCP per contabilità con AI" -description: "Collega DATEV a MCP. Accedi a clienti, documenti contabili e dati HR con agenti AI. Il primo server MCP per DATEV." +title: "Collegare le DATEV Online APIs a MCP — agenti AI per la contabilità" +description: "Collega le API ufficiali DATEV Online (accounting-clients + accounting-documents) a qualsiasi agente AI compatibile MCP. OIDC Authorization Code + PKCE contro login.datev.de, legato a un vero DATEV-Konto." category: "connectors" -keyword: "DATEV MCP Server, DATEV AI, DATEV con Claude, DATEV ChatGPT" +keyword: "DATEV MCP Server, DATEV AI, DATEV con Claude, DATEV ChatGPT, Steuerberater AI" publishedAt: "2026-03-15" adapterSlug: "datev" --- -## DATEV con Agenti AI via MCP +## DATEV con agenti AI via MCP -DATEV è la piattaforma contabile dominante in Germania. Con AnythingMCP, colleghi le API REST ufficiali DATEV a qualsiasi agente AI compatibile MCP. +DATEV è la piattaforma di contabilità e fiscalità dominante in Germania, usata praticamente da ogni commercialista (Steuerberater). Questo connettore avvolge le **DATEV Online APIs** ufficiali, così un agente AI compatibile MCP (Claude, ChatGPT, Gemini, Copilot, Cursor) può leggere i tuoi Mandanten (clienti) e i metadati DATEV Unternehmen online (DUO). -## Configurazione +> **Leggere prima.** Le DATEV Online APIs **non sono plug-and-play**. Servono (a) un'app nel DATEV-Entwicklerportal, (b) un abbonamento per ogni prodotto API, (c) un utente DATEV-Konto reale con SmartLogin/SmartCard e (d) un'approvazione di produzione DATEV per uscire dalla sandbox. + +## Cosa copre oggi il connettore + +Tutti i valori sotto vengono dagli OpenAPI ufficiali su `https://developer.datev.de/mediator/apis//document`. + +| Tool | Prodotto API | Endpoint | Scope | +|------|--------------|----------|-------| +| `datev_list_clients` | accounting-clients v2 | `GET /clients` | `datev:accounting:clients` | +| `datev_get_client` | accounting-clients v2 | `GET /clients/{id}` | `datev:accounting:clients` | +| `datev_documents_list_clients` | accounting-documents v2 | `GET /clients` | `accounting:clients:read` | +| `datev_get_documents_client` | accounting-documents v2 | `GET /clients/{id}` | `accounting:clients:read` | +| `datev_list_document_types` | accounting-documents v2 | `GET /clients/{id}/document-types` | `accounting:documents` | +| `datev_get_duo_version` | accounting-documents v2 | `GET /clients/{id}/duo-version` | `accounting:clients:read` | + +### Cosa **non** è coperto al momento + +Tre endpoint di upload esistono su `accounting-documents v2` ma richiedono `multipart/form-data` con una parte binaria. L'engine REST oggi serializza i campi form-data con `String(v)`, che corrompe PDF/immagini binarie. Arriveranno quando l'engine accetterà `Buffer`/base64: + +- `POST /clients/{id}/documents` — ID documento auto-assegnato +- `PUT /clients/{id}/documents/{guid}` — GUID RFC4122 assegnato dal chiamante +- `PUT /clients/{id}/documents/stapled` — più documenti in una sola richiesta + +Fuori scope: `accounting:dataexchange`, `accounting:dxso-jobs`, `accounting:extf-files`, HR/Lohn (`hr-documents`, `hr-imports`, `hr-payrollreports`, `eau-api`), DMS, addressee, cashregister e l'IdP next-gen `datev_idp_next` (`signin.datev.de/datevam/...`). + +## Prerequisiti — checklist nel portale DATEV + +1. Registrazione al [DATEV-Entwicklerportal](https://developer.datev.de). Unisciti a o crea un'organizzazione. +2. Crea un'app: + - **Authorization Flow**: *OpenID Connect Authorization Code Flow* (non Hybrid) + - **Client Type**: *Confidential* (refresh token rolling di 2 anni; necessario per operazioni unattended) + - **Redirect URLs**: `https:///api/mcp-oauth/callback` (il path deve combaciare esatto — `http://localhost` solo su sandbox) +3. Abbonamento a *accounting-clients v2* **e** *accounting-documents v2* sulla [pagina del programma DATEV](https://developer.datev.de/en/products/988700e4-e0c5-40bf-814b-cd7327dad67a). Condividono lo stesso abbonamento OAuth. +4. Conserva `Client ID` e `Client Secret`. Le app partono in **sandbox**; per `*.api.datev.de` (produzione) serve la production-approval-review DATEV. +5. Utente DATEV-Konto con SmartLogin o SmartCard/mIDentity. `client_credentials` **non** è supportato. + +## Installazione ```bash git clone https://github.com/HelpCode-ai/anythingmcp.git cd anythingmcp && docker compose up -d ``` -Registrati al [DATEV Developer Portal](https://developer.datev.de), importa l'adattatore e configura le credenziali OAuth 2.0. +Apri `http://localhost:3000/connectors/store`, installa l'adapter DATEV e configura: + +| Variabile env | Valore | +|---------------|--------| +| `DATEV_CLIENT_ID` | dal portale DATEV | +| `DATEV_CLIENT_SECRET` | dal portale DATEV | + +Il connettore ha **URL di produzione di default**: +- Authorization: `https://login.datev.de/openid/authorize` +- Token: `https://api.datev.de/token` +- Base API: `https://accounting-clients.api.datev.de/platform/v2` + `https://accounting-documents.api.datev.de/platform/v2` + +Inoltre inietta automaticamente `X-DATEV-Client-Id: ` su ogni chiamata (lo schema apiKey `client_id` è **richiesto su ogni endpoint DATEV** in aggiunta al Bearer token). + +## Passare alla sandbox + +Le nuove app DATEV partono in sandbox finché non hanno production-approval. Per puntare il connettore alla sandbox, **dopo l'installazione** modifica l'`authConfig` salvato: + +| Campo | Valore sandbox | +|-------|----------------| +| `authorizationUrl` | `https://login.datev.de/openidsandbox/authorize` | +| `tokenUrl` | `https://sandbox-api.datev.de/token` | + +E in ogni `endpointMapping.path` dei tool sostituisci `platform` con `platform-sandbox`: +- `https://accounting-clients.api.datev.de/platform-sandbox/v2/...` +- `https://accounting-documents.api.datev.de/platform-sandbox/v2/...` + +Una iterazione futura può scorciare questo via env var `DATEV_ENV=sandbox`. + +## OAuth una tantum + +Dopo l'installazione, avvia il flusso Authorization Code + PKCE: + +```bash +curl -X POST http://localhost:4000/api/connectors//oauth/authorize \ + -H "Authorization: Bearer " +``` + +La risposta contiene un `authorizationUrl`. Aprilo nel browser, autenticati con il DATEV-Konto, approva gli scope: + +``` +datev:accounting:clients +accounting:clients:read +accounting:documents +``` + +(Nota: `openid` è il nome dell'issuer sul flow attuale `datev_openid`, **non** uno scope. Lo schema OpenAPI security non lo include.) + +DATEV reindirizza su `/api/mcp-oauth/callback`; la piattaforma salva un refresh token cifrato nell'`authConfig`. Da qui in poi l'engine rinnova l'access token silenziosamente 5 minuti prima della scadenza. I confidential client ricevono un refresh token rolling di 2 anni. + +## Uso dei tool + +Ogni tool per-cliente accetta un parametro `clientId` — è l'**UUID del Mandant** (RFC4122 `8-4-4-4-12`), **diverso dal tuo `DATEV_CLIENT_ID` OAuth**. Chiama `datev_list_clients` per primo per ottenere gli UUID. + +```text +agent: Lista i miei Mandanten DATEV +→ datev_list_clients +← [{ id: "a0b1c2d3-…", consultant_number: 12345, client_number: 1, name: "Müller GmbH" }, …] + +agent: Quali tipi di documento sono configurati per Müller GmbH su DUO? +→ datev_list_document_types(clientId: "a0b1c2d3-…") + +agent: Quali formati file accetta DUO per Müller GmbH? +→ datev_get_duo_version(clientId: "a0b1c2d3-…") +``` + +## Nota sui due tool "list_clients" + +`datev_list_clients` chiama accounting-clients v2 — la lista canonica di ogni Mandant per cui il tuo utente è abilitato. + +`datev_documents_list_clients` chiama accounting-documents v2 — solo il sottoinsieme di quei Mandanten con abbonamento **DATEV Unternehmen online** attivo (ovvero pronti a ricevere upload di documenti). Usa questo prima di un upload per sapere quali Mandanten lo accetteranno. + +## CSV / EXTF — l'alternativa pragmatica per PMI + +Senza contratto partner DATEV / production-approval, l'Online API non è una strada. Il percorso d'integrazione standard per le PMI è generare un **CSV DATEV-ASCII / EXTF Buchungsstapel** (`EXTF_Buchungsstapel.csv`, specifica formato 700/810) che il commercialista importa in *Rechnungswesen pro*. Niente OAuth, niente abbonamento al portale, niente production-approval. Un adapter dedicato per la generazione EXTF è in roadmap; nel frattempo la gem Ruby [ledermann/datev](https://github.com/ledermann/datev) è l'implementazione di riferimento del formato. -## Casi d'Uso +## Casi d'uso -- **"Lista tutti i miei clienti DATEV"** -- **"Mostra i documenti caricati questo mese"** -- **"Carica questa fattura su DATEV Belege online"** +- **"Lista tutti i miei Mandanten DATEV"** +- **"Quali miei Mandanten hanno abbonamento DUO?"** +- **"Quali tipi di documento sono configurati per il Mandant Müller?"** +- **"Quali formati file accetta DUO per il cliente a0b1c2d3-…?"** diff --git a/packages/backend/src/adapters/de/datev.json b/packages/backend/src/adapters/de/datev.json index 4f7743c..302aab1 100644 --- a/packages/backend/src/adapters/de/datev.json +++ b/packages/backend/src/adapters/de/datev.json @@ -1,120 +1,152 @@ { "slug": "datev", - "name": "DATEV Accounting", - "description": "Connect to DATEV accounting systems via the official DATEV Online APIs. Access accounting documents, clients, payroll data, and HR reporting. Used by nearly every German tax consultant.", + "name": "DATEV Online APIs", + "description": "Read accounting Mandanten (clients), document types and DATEV Unternehmen online (DUO) version metadata from DATEV's official Online APIs. OAuth2 Authorization Code + PKCE bound to a real DATEV-Konto. Required by virtually every German tax consultant (Steuerberater).", + "instructions": "**Important — this connector is NOT plug-and-play.** DATEV's Online APIs require:\n\n1. A registered app on the DATEV-Entwicklerportal (https://developer.datev.de) → **Confidential client** + **OpenID Connect Authorization Code Flow**. Set the redirect URI to `/api/mcp-oauth/callback`.\n2. A subscription to each API product you want to use — currently `accounting-clients v2.0` and `accounting-documents v2.0`. Both are *Already subscribed* checks on the product page.\n3. A real DATEV-Konto user with SmartLogin or SmartCard/mIDentity. DATEV does NOT expose `client_credentials` — every call is on-behalf-of a human accountant. Confidential clients get 2-year rolling refresh tokens (the engine refreshes proactively).\n4. For *.api.datev.de (production) you must complete DATEV's production-approval review. Until then, point the connector at the **sandbox** (see below).\n\n**Authentication endpoints** (canonical, from `https://login.datev.de/openid/.well-known/openid-configuration`):\n- Production: `authorize=https://login.datev.de/openid/authorize`, `token=https://api.datev.de/token`\n- Sandbox: `authorize=https://login.datev.de/openidsandbox/authorize`, `token=https://sandbox-api.datev.de/token`\n\n**Setup**:\n1. Set `DATEV_CLIENT_ID` and `DATEV_CLIENT_SECRET` (from the DATEV portal).\n2. Import this adapter — defaults to **production** auth URLs.\n3. Run the one-time OAuth flow: `POST /api/connectors/{id}/oauth/authorize` → open the returned URL → log in with your DATEV-Konto → the platform stores an encrypted refresh token automatically.\n4. From now on every call sends `Authorization: Bearer ` AND the mandatory `X-DATEV-Client-Id: ` header automatically.\n\n**Switching to sandbox** (DATEV apps default to sandbox after creation, until production approval): after import, edit the connector's `authConfig`:\n- `authorizationUrl` → `https://login.datev.de/openidsandbox/authorize`\n- `tokenUrl` → `https://sandbox-api.datev.de/token`\n\nAND replace `platform` with `platform-sandbox` in each tool's `endpointMapping.path` (5 paths). A future iteration may expose this via env-var switching.\n\n**Scopes requested**: `datev:accounting:clients accounting:clients:read accounting:documents`. These cover both API products in one consent screen. Note: the current DATEV `datev_openid` flow does NOT include `openid` in its scope list (it's the issuer name, not a requested scope) — confirmed in the OpenAPI security schemes.\n\n**Mandant scoping**: every per-client tool takes a `clientId` parameter — that's the **Mandant UUID** (RFC4122 8-4-4-4-12), returned by `datev_list_clients`. **Distinct** from `DATEV_CLIENT_ID` (the OAuth app identifier, sent in the header).\n\n**Not exposed here** (engine limitation):\n- `POST /clients/{id}/documents`, `PUT /clients/{id}/documents/{guid}`, `PUT /clients/{id}/documents/stapled`: all require `multipart/form-data` with a binary file part. The REST engine currently serializes form-data field values via `String(v)`, which corrupts binary PDFs/images. These upload tools land once the engine accepts `Buffer`/base64 in form-data values.\n- `accounting:dataexchange`, `accounting:dxso-jobs`, `accounting:extf-files`, HR / Lohn, DMS, addressee: separate adapters per product line.\n- The `datev_idp_next` security option (next-gen `signin.datev.de/datevam/...` IdP) is defined in the spec but not yet exposed here.", "region": "de", "category": "accounting", "icon": "datev", - "docsUrl": "https://developer.datev.de/en/products", - "requiredEnvVars": [ - "DATEV_CLIENT_ID", - "DATEV_CLIENT_SECRET", - "DATEV_TOKEN_URL", - "DATEV_AUTH_URL" - ], + "docsUrl": "https://developer.datev.de/en/products/988700e4-e0c5-40bf-814b-cd7327dad67a", + "requiredEnvVars": ["DATEV_CLIENT_ID", "DATEV_CLIENT_SECRET"], "connector": { "name": "DATEV Online APIs", "type": "REST", - "baseUrl": "https://accounting-documents.api.datev.de/platform/v2", + "baseUrl": "https://accounting-clients.api.datev.de/platform/v2", "authType": "OAUTH2", "authConfig": { "clientId": "{{DATEV_CLIENT_ID}}", "clientSecret": "{{DATEV_CLIENT_SECRET}}", - "tokenUrl": "{{DATEV_TOKEN_URL}}", - "authorizationUrl": "{{DATEV_AUTH_URL}}", - "scopes": "openid accounting:documents" + "authorizationUrl": "https://login.datev.de/openid/authorize", + "tokenUrl": "https://api.datev.de/token", + "scopes": "datev:accounting:clients accounting:clients:read accounting:documents" + }, + "headers": { + "X-DATEV-Client-Id": "{{DATEV_CLIENT_ID}}" } }, "tools": [ { "name": "datev_list_clients", - "description": "List DATEV accounting clients. Returns client number, name, and ID for use with other DATEV API calls.", + "description": "List DATEV accounting Mandanten (clients) your DATEV-Konto user is provisioned for, from the accounting-clients v2 master-data product. Returns each client's UUID, consultant number, client number and display name. Use the returned UUID as the `clientId` parameter on all other tools.", "parameters": { "type": "object", - "properties": {} + "properties": { + "skip": { + "type": "integer", + "description": "Pagination offset (>= 0)." + }, + "top": { + "type": "integer", + "description": "Max items per page (1-100)." + } + } }, "endpointMapping": { "method": "GET", - "path": "/clients", + "path": "https://accounting-clients.api.datev.de/platform/v2/clients", + "queryParams": { + "skip": "$skip", + "top": "$top" + }, "headers": { "Accept": "application/json" } } }, { - "name": "datev_upload_document", - "description": "Upload an accounting document (invoice, receipt) to DATEV Belege online for a specific client.", + "name": "datev_get_client", + "description": "Get one Mandant's master data (consultant/client number, name, address) from accounting-clients v2.", "parameters": { "type": "object", "properties": { "clientId": { "type": "string", - "description": "The DATEV client ID" - }, - "documentGuid": { - "type": "string", - "description": "Unique GUID for the document (RFC4122 format: 8-4-4-4-12)" + "description": "Mandant UUID (RFC4122 8-4-4-4-12). Get this from datev_list_clients." } }, - "required": [ - "clientId", - "documentGuid" - ] + "required": ["clientId"] }, "endpointMapping": { - "method": "PUT", - "path": "/clients/{clientId}/documents/{documentGuid}", + "method": "GET", + "path": "https://accounting-clients.api.datev.de/platform/v2/clients/{clientId}", "headers": { - "Content-Type": "application/octet-stream" + "Accept": "application/json" } } }, { - "name": "datev_list_documents", - "description": "List accounting documents for a DATEV client. Returns document metadata including type, date, and processing status.", + "name": "datev_documents_list_clients", + "description": "List the subset of Mandanten that have DATEV Unternehmen online (DUO) document access via the accounting-documents v2 product. This may be smaller than datev_list_clients — only clients with active DUO subscriptions appear here.", + "parameters": { + "type": "object", + "properties": {} + }, + "endpointMapping": { + "method": "GET", + "path": "https://accounting-documents.api.datev.de/platform/v2/clients", + "headers": { + "Accept": "application/json" + } + } + }, + { + "name": "datev_get_documents_client", + "description": "Get one Mandant's basic data as exposed by the accounting-documents v2 product (the DUO view, distinct from the accounting-clients master record).", "parameters": { "type": "object", "properties": { "clientId": { "type": "string", - "description": "The DATEV client ID" + "description": "Mandant UUID (from datev_list_clients or datev_documents_list_clients)." } }, - "required": [ - "clientId" - ] + "required": ["clientId"] }, "endpointMapping": { "method": "GET", - "path": "/clients/{clientId}/documents", + "path": "https://accounting-documents.api.datev.de/platform/v2/clients/{clientId}", "headers": { "Accept": "application/json" } } }, { - "name": "datev_get_document", - "description": "Get details of a specific accounting document by GUID.", + "name": "datev_list_document_types", + "description": "List the document types (Belegtypen) configured for a Mandant on DATEV Unternehmen online — needed before uploading documents so you know which `documentType` values are accepted.", "parameters": { "type": "object", "properties": { "clientId": { "type": "string", - "description": "The DATEV client ID" - }, - "documentGuid": { + "description": "Mandant UUID (from datev_list_clients)." + } + }, + "required": ["clientId"] + }, + "endpointMapping": { + "method": "GET", + "path": "https://accounting-documents.api.datev.de/platform/v2/clients/{clientId}/document-types", + "headers": { + "Accept": "application/json" + } + } + }, + { + "name": "datev_get_duo_version", + "description": "Get the DATEV Unternehmen online (DUO) version and the permitted file extensions for document upload on a given Mandant. Useful before generating uploads to know what file formats DUO will accept (PDF, JPG, TIFF, etc.) and any DUO-version-specific limits.", + "parameters": { + "type": "object", + "properties": { + "clientId": { "type": "string", - "description": "The document GUID" + "description": "Mandant UUID (from datev_list_clients)." } }, - "required": [ - "clientId", - "documentGuid" - ] + "required": ["clientId"] }, "endpointMapping": { "method": "GET", - "path": "/clients/{clientId}/documents/{documentGuid}", + "path": "https://accounting-documents.api.datev.de/platform/v2/clients/{clientId}/duo-version", "headers": { "Accept": "application/json" }