@casys/mcp-einvoice 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,54 +1,38 @@
1
- # @casys/mcp-einvoice
1
+ # mcp-einvoice
2
2
 
3
- MCP server for French e-invoicingPA-agnostic via the adapter pattern.
3
+ Serveur MCP pour la facturation électroniqueagnostique plateforme via le pattern adapter.
4
4
 
5
- ## Architecture
5
+ <p align="center">
6
+ <img src="docs/logos/iopole.svg" alt="Iopole" height="40">&nbsp;&nbsp;&nbsp;&nbsp;
7
+ <img src="docs/logos/storecove.png" alt="Storecove" height="40">&nbsp;&nbsp;&nbsp;&nbsp;
8
+ <img src="docs/logos/superpdp.svg" alt="Super PDP" height="40">
9
+ </p>
6
10
 
7
- ```
8
- ┌──────────────────────────────────────────────────┐
9
- │ MCP Tools (27 tools, einvoice_*) │
10
- │ invoice · directory · status · reporting · webhook │
11
- ├──────────────────────────────────────────────────┤
12
- │ MCP Apps (4 viewers) │
13
- │ invoice-viewer · doclist-viewer │
14
- │ status-timeline · directory-card │
15
- ├──────────────────────────────────────────────────┤
16
- │ EInvoiceAdapter (interface) │
17
- │ PA-agnostic: emitInvoice, searchInvoices, ... │
18
- ├──────────┬───────────────────────────────────────┤
19
- │ Iopole │ Autres PA via EInvoiceAdapter │
20
- │ (REST) │ (ajout sans toucher aux tools) │
21
- └──────────┴───────────────────────────────────────┘
22
- ```
11
+ ## Pourquoi
12
+
13
+ La réforme de la facturation électronique en France (sept. 2026) impose l'utilisation de Plateformes Agréées (PA). Il en existe 106+, chacune avec sa propre API. Ce serveur MCP expose **une interface unique** pour toutes, avec 39 tools et 6 viewers interactifs.
23
14
 
24
- Chaque PA (Plateforme Agréée) implémente `EInvoiceAdapter`. Les tools MCP appellent l'adapter, jamais l'API directement.
15
+ ## Adapters
25
16
 
26
- ## Configuration
17
+ | | Adapter | Scope | Tools | Base |
18
+ |---|---|---|---|---|
19
+ | <img src="docs/logos/iopole.svg" height="16"> | **Iopole** | PA française, B2B | 39/39 | BaseAdapter |
20
+ | <img src="docs/logos/storecove.png" height="16"> | **Storecove** | Peppol AP, 40+ pays | 19/39 | BaseAdapter |
21
+ | <img src="docs/logos/superpdp.svg" height="16"> | **Super PDP** | PA française, B2B | 20/39 | AfnorBaseAdapter |
27
22
 
28
- ### Variables d'environnement
23
+ `BaseAdapter` fournit des stubs `NotSupportedError` pour les 45 méthodes de l'interface `EInvoiceAdapter`. Les PA françaises avec AFNOR héritent d'`AfnorBaseAdapter` (socle [AFNOR XP Z12-013](https://norminfo.afnor.org/norme/pr-xp-a00-002/standardisation-api-odpdp/211970)) qui ajoute les opérations flow. Les autres étendent `BaseAdapter` directement.
24
+
25
+ Le filtrage par `capabilities` assure que le LLM ne voit que les tools supportés par l'adapter actif.
26
+
27
+ ## Configuration rapide
29
28
 
30
29
  ```bash
31
- # Choix du provider (default: iopole)
32
- EINVOICE_ADAPTER=iopole
33
-
34
- # Config Iopole — OAuth2 client credentials
35
- IOPOLE_API_URL=https://api.ppd.iopole.fr/v1 # sandbox
36
- IOPOLE_CLIENT_ID=your-client-id
37
- IOPOLE_CLIENT_SECRET=your-client-secret
38
- IOPOLE_CUSTOMER_ID=your-customer-id # required since 2026-02-01
39
-
40
- # Optionnel — token endpoint Keycloak (default: production)
41
- # Sandbox : https://auth.ppd.iopole.fr/realms/iopole/protocol/openid-connect/token
42
- IOPOLE_AUTH_URL=https://auth.iopole.com/realms/iopole/protocol/openid-connect/token
43
-
44
- # Sécurité (optionnel — mode HTTP du serveur MCP)
45
- MCP_AUTH_PROVIDER=oidc
46
- MCP_AUTH_ISSUER=https://auth.example.com
47
- MCP_AUTH_AUDIENCE=mcp-einvoice
48
- MCP_AUTH_JWKS_URI=https://auth.example.com/.well-known/jwks.json
30
+ cp .env.example .env
31
+ # Remplir les variables de l'adapter choisi, puis :
32
+ deno task serve # HTTP mode (port 3015)
49
33
  ```
50
34
 
51
- ### MCP config (stdio mode)
35
+ ### MCP config (Claude Desktop / stdio)
52
36
 
53
37
  ```json
54
38
  {
@@ -59,167 +43,128 @@ MCP_AUTH_JWKS_URI=https://auth.example.com/.well-known/jwks.json
59
43
  "env": {
60
44
  "EINVOICE_ADAPTER": "iopole",
61
45
  "IOPOLE_API_URL": "https://api.ppd.iopole.fr/v1",
62
- "IOPOLE_CLIENT_ID": "your-client-id",
63
- "IOPOLE_CLIENT_SECRET": "your-client-secret",
64
- "IOPOLE_CUSTOMER_ID": "your-customer-id"
46
+ "IOPOLE_CLIENT_ID": "...",
47
+ "IOPOLE_CLIENT_SECRET": "...",
48
+ "IOPOLE_CUSTOMER_ID": "..."
65
49
  }
66
50
  }
67
51
  }
68
52
  }
69
53
  ```
70
54
 
71
- ### HTTP mode
72
-
73
- ```bash
74
- deno run --allow-all server.ts --http --port=3015
75
- ```
55
+ Remplacer `EINVOICE_ADAPTER` par `storecove` ou `superpdp` avec les variables correspondantes (voir `.env.example`).
76
56
 
77
- Options :
78
- - `--http` — mode HTTP (default: stdio)
79
- - `--port=3015` — port HTTP (default: 3015)
80
- - `--hostname=0.0.0.0` — hostname (default: 0.0.0.0)
81
- - `--adapter=iopole` — override le provider (default: env `EINVOICE_ADAPTER` ou `iopole`)
82
- - `--categories=invoice,status` — filtrer les catégories de tools
57
+ ### Options serveur
83
58
 
84
- **Note** : en mode HTTP, le `generated-store` (flow generate → emit) est in-memory et single-instance. Ne pas déployer derrière un load-balancer sans sticky sessions.
59
+ ```
60
+ --http Mode HTTP (default: stdio)
61
+ --port=3015 Port HTTP
62
+ --hostname=localhost Bind address (default: localhost)
63
+ --adapter=iopole Override adapter (default: env EINVOICE_ADAPTER)
64
+ --categories=invoice Filtrer les catégories de tools
65
+ ```
85
66
 
86
- ## Tools (27)
67
+ ## Architecture
87
68
 
88
- | Catégorie | N | Tools | Description |
89
- |-----------|---|-------|-------------|
90
- | **invoice** | 13 | `emit`, `search`, `get`, `download`, `download_readable`, `files`, `attachments`, `download_file`, `mark_seen`, `not_seen`, `generate_cii`, `generate_ubl`, `generate_facturx` | Émission, recherche, téléchargement, génération CII/UBL/Factur-X |
91
- | **directory** | 3 | `fr_search`, `int_search`, `peppol_check` | Annuaire PPF (France) + Peppol (international) |
92
- | **status** | 4 | `send`, `history`, `not_seen`, `mark_seen` | Cycle de vie facture (APPROVED, REFUSED, DISPUTED, PAYMENT_SENT...) |
93
- | **reporting** | 2 | `invoice_transaction`, `transaction` | E-reporting DGFiP (B2C, international) |
94
- | **webhook** | 5 | `list`, `get`, `create`, `update`, `delete` | Notifications temps réel |
69
+ ```
70
+ ┌───────────────────────────────────────────────┐
71
+ │ 39 MCP Tools (einvoice_*) │
72
+ │ invoice · directory · status · reporting │
73
+ │ webhook · config │
74
+ ├───────────────────────────────────────────────┤
75
+ │ 6 MCP Apps (viewers React) │
76
+ │ invoice · doclist · timeline · card · │
77
+ │ directory-list · action │
78
+ ├───────────────────────────────────────────────┤
79
+ │ EInvoiceAdapter (interface, 45 methods) │
80
+ │ + capabilities → filtrage tools dynamique │
81
+ ├──────────┬────────────────────────────────────┤
82
+ │ BaseAdapter (abstract, NotSupported stubs) │
83
+ ├──────────┼────────────────────────────────────┤
84
+ │ AfnorBase│ Direct │
85
+ │ (AFNOR) │ │
86
+ │ ┌──────┐ │ ┌─────────┐ ┌───────────┐ │
87
+ │ │ SPDP │ │ │ Iopole │ │ Storecove │ │
88
+ │ └──────┘ │ └─────────┘ └───────────┘ │
89
+ └──────────┴────────────────────────────────────┘
90
+ ```
95
91
 
96
- Tous les noms de tools sont préfixés `einvoice_<category>_` (ex: `einvoice_invoice_search`).
92
+ ## Tools
97
93
 
98
- ### Flow generate preview → emit
94
+ | Catégorie | Tools |
95
+ |-----------|-------|
96
+ | **invoice** (11) | submit, search, get, download, download_readable, files, attachments, download_file, generate_cii, generate_ubl, generate_facturx |
97
+ | **directory** (3) | fr_search, int_search, peppol_check |
98
+ | **status** (2) | send, history |
99
+ | **reporting** (2) | invoice_transaction, transaction |
100
+ | **webhook** (5) | list, get, create, update, delete |
101
+ | **config** (16) | customer_id, entities_list, entity_get, entity_create_legal, entity_create_office, enroll_fr, entity_claim, entity_delete, network_register, network_register_by_id, network_unregister, identifier_create, identifier_create_by_scheme, identifier_delete, entity_configure, claim_delete |
99
102
 
100
- 1. **Generate** (`generate_cii`, `generate_ubl`, `generate_facturx`) : Génère le XML/PDF, stocke le fichier côté serveur, retourne un `generated_id` + preview pour le viewer
101
- 2. **Preview** : Le `invoice-viewer` affiche la facture avec un bouton "Déposer"
102
- 3. **Emit** (`emit`) : Accepte `generated_id` (consomme le fichier stocké) ou `file_base64` + `filename` direct
103
+ Tous préfixés `einvoice_<category>_`. Chaque tool déclare ses `requires` seuls ceux supportés par l'adapter actif sont exposés au LLM.
103
104
 
104
- Les fichiers générés expirent après 10 minutes.
105
+ ### Flow generate preview submit
105
106
 
106
- ## MCP Apps (4 viewers)
107
+ 1. `generate_*` stocke le fichier, retourne `generated_id` + preview viewer
108
+ 2. Le viewer affiche la facture avec bouton "Déposer"
109
+ 3. `submit` consomme le `generated_id` (ou accepte `file_base64` direct)
107
110
 
108
- | Viewer | Tools associés | Description |
109
- |--------|---------------|-------------|
110
- | **invoice-viewer** | `get`, `generate_*` | Facture détaillée avec actions (accepter, rejeter, contester, marquer lu, télécharger, déposer) |
111
- | **doclist-viewer** | `search`, `not_seen`, `fr_search`, `int_search`, `webhook_list` | Table générique avec drill-down (clic → appel tool) |
112
- | **status-timeline** | `history` | Timeline verticale des changements de statut |
113
- | **directory-card** | `fr_search` (single result) | Fiche entreprise avec SIREN/SIRET, réseaux, détails |
111
+ ## Viewers (MCP Apps)
114
112
 
115
- Build des viewers :
113
+ | Viewer | Usage |
114
+ |--------|-------|
115
+ | **invoice-viewer** | Facture détaillée + actions (accepter, rejeter, déposer) |
116
+ | **doclist-viewer** | Table avec drill-down, recherche, filtres direction/statut |
117
+ | **status-timeline** | Timeline verticale des changements de statut |
118
+ | **directory-card** | Fiche entreprise (SIREN/SIRET, réseaux) |
119
+ | **directory-list** | Résultats annuaire — cartes avec expand, recherche client |
120
+ | **action-result** | Feedback visuel d'action (enroll, register) |
116
121
 
117
122
  ```bash
118
- cd src/ui && node build-all.mjs
123
+ cd src/ui && node build-all.mjs # Rebuild après modification TSX
119
124
  ```
120
125
 
121
- ## Utilisation directe de l'adapter
126
+ ## Ajouter un adapter
122
127
 
123
- ```typescript
124
- import { createIopoleAdapter } from "@casys/mcp-einvoice";
125
-
126
- const adapter = createIopoleAdapter();
127
-
128
- // Rechercher des factures (Lucene syntax)
129
- const results = await adapter.searchInvoices({
130
- q: 'status:accepted AND direction:received',
131
- expand: "businessData",
132
- offset: 0,
133
- limit: 20,
134
- });
135
-
136
- // Envoyer un statut
137
- await adapter.sendStatus({
138
- invoiceId: "uuid-de-la-facture",
139
- code: "APPROVED",
140
- message: "Facture validée",
141
- });
142
-
143
- // Chercher dans l'annuaire PPF
144
- const company = await adapter.searchDirectoryFr({
145
- q: 'siret:"43446637100011"',
146
- });
147
-
148
- // Générer une facture CII
149
- const xml = await adapter.generateCII({
150
- invoice: { invoiceId: "F-001", seller: { ... }, buyer: { ... }, ... },
151
- flavor: "EN16931",
152
- });
153
- ```
154
-
155
- ## Ajouter un adapter (nouveau PA)
156
-
157
- 1. Créer `src/adapters/my-pa.ts` implémentant `EInvoiceAdapter`
158
- 2. Ajouter le case dans `server.ts` → `createAdapter()`
128
+ **PA française avec AFNOR** → `extends AfnorBaseAdapter` (socle AFNOR gratuit, override le natif) :
159
129
 
160
130
  ```typescript
161
- import type { EInvoiceAdapter } from "../adapter.ts";
162
-
163
- export class MyPAAdapter implements EInvoiceAdapter {
131
+ export class MyPAAdapter extends AfnorBaseAdapter {
164
132
  readonly name = "my-pa";
165
- // Implémenter les 27 méthodes de l'interface
166
- }
167
- ```
133
+ readonly capabilities = new Set(["emitInvoice", "searchInvoices", ...]);
134
+ private client: MyPAClient;
168
135
 
169
- L'interface `EInvoiceAdapter` est définie dans `src/adapter.ts` — 27 méthodes couvrant factures, annuaire, statuts, reporting et webhooks.
136
+ constructor(client: MyPAClient, afnor: AfnorClient | null) {
137
+ super(afnor); // ou super(null) si pas encore d'AFNOR
138
+ this.client = client;
139
+ }
170
140
 
171
- ## Node.js
141
+ override async generateCII(req) { return this.client.convert(req); }
142
+ // ... override les extras, hériter le reste
143
+ }
144
+ ```
172
145
 
173
- Build single-file CLI via esbuild :
146
+ **PA française sans AFNOR** `extends BaseAdapter` (override toutes les méthodes avec l'API native, comme Iopole).
174
147
 
175
- ```bash
176
- ./scripts/build-node.sh
177
- # Produit dist-node/bin/mcp-einvoice.mjs (~1.3MB)
178
- ```
148
+ **Plateforme non-française** → `extends BaseAdapter` directement (comme Storecove).
179
149
 
180
- Le script swap `runtime.ts` par `runtime.node.ts` et strip les extensions `.ts` des imports.
150
+ Guide complet : `src/adapters/README.md`.
181
151
 
182
152
  ## Structure
183
153
 
184
154
  ```
185
- ├── deno.json # Package @casys/mcp-einvoice
186
- ├── mod.ts # Public API
187
- ├── server.ts # MCP server (stdio + HTTP)
188
- ├── scripts/
189
- │ └── build-node.sh # esbuild single-file build
190
- └── src/
191
- ├── adapter.ts # EInvoiceAdapter interface (26 méthodes)
192
- ├── generated-store.ts # Temp file store (generate → emit flow)
193
- ├── adapters/
194
- └── iopole.ts # IopoleAdapter
195
- ├── api/
196
- └── iopole-client.ts # HTTP client + OAuth2 token provider
197
- ├── runtime.ts # Deno runtime (env vars)
198
- ├── runtime.node.ts # Node.js runtime
199
- ├── tools/
200
- │ ├── types.ts # EInvoiceTool, EInvoiceToolContext
201
- │ ├── mod.ts # Registry (27 tools)
202
- │ ├── invoice.ts # 13 tools
203
- │ ├── directory.ts # 3 tools
204
- │ ├── status.ts # 4 tools
205
- │ ├── reporting.ts # 2 tools
206
- │ └── webhook.ts # 5 tools
207
- ├── testing/
208
- │ └── helpers.ts # Mock fetch, mock adapter
209
- └── ui/
210
- ├── build-all.mjs
211
- ├── shared/ # Theme, brand, refresh
212
- ├── invoice-viewer/ # Viewer facture interactif
213
- ├── doclist-viewer/ # Table générique drill-down
214
- ├── status-timeline/ # Timeline verticale statuts
215
- └── directory-card/ # Fiche entreprise
155
+ server.ts # MCP server (stdio + HTTP)
156
+ src/
157
+ ├── adapter.ts # EInvoiceAdapter (45 methods + capabilities)
158
+ ├── client.ts # Tools registry + capability filtering
159
+ ├── adapters/
160
+ │ ├── base-adapter.ts # BaseAdapter (abstract, NotSupported stubs)
161
+ ├── afnor/ # Socle AFNOR XP Z12-013 (shared)
162
+ │ │ ├── base-adapter.ts # AfnorBaseAdapter (extends BaseAdapter)
163
+ │ │ └── client.ts # AfnorClient (3 flow endpoints)
164
+ ├── shared/oauth2.ts # OAuth2 token provider (shared)
165
+ ├── iopole/ # PA française — extends BaseAdapter
166
+ ├── storecove/ # Peppol AP extends BaseAdapter
167
+ │ └── superpdp/ # PA française extends AfnorBaseAdapter
168
+ ├── tools/ # 39 tools (6 catégories)
169
+ └── ui/ # 6 viewers React (single-file HTML)
216
170
  ```
217
-
218
- ## Iopole API
219
-
220
- - Production : `https://api.iopole.com/v1`
221
- - Sandbox : `https://api.ppd.iopole.fr/v1`
222
- - Search : `https://api.ppd.iopole.fr/v1.1/invoice/search` (version v1.1)
223
- - Auth : OAuth2 `client_credentials` (token TTL 10 min, auto-refresh 60s avant expiry)
224
- - Token endpoint : `https://auth.iopole.com/realms/iopole/protocol/openid-connect/token`
225
- - Header `customer-id` obligatoire sur toutes les requêtes (depuis 2026-02-01)