@casys/mcp-einvoice 0.1.1 → 0.1.3

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,47 @@
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
4
+ pattern adapter.
4
5
 
5
- ## Architecture
6
+ <p align="center">
7
+ <img src="docs/logos/iopole.svg" alt="Iopole" height="40">&nbsp;&nbsp;&nbsp;&nbsp;
8
+ <img src="docs/logos/storecove.png" alt="Storecove" height="40">&nbsp;&nbsp;&nbsp;&nbsp;
9
+ <img src="docs/logos/superpdp.svg" alt="Super PDP" height="40">
10
+ </p>
6
11
 
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
- ```
12
+ ## Pourquoi
13
+
14
+ La réforme de la facturation électronique en France (sept. 2026) impose
15
+ l'utilisation de Plateformes Agréées (PA). Il en existe 106+, chacune avec sa
16
+ propre API. Ce serveur MCP expose **une interface unique** pour toutes, avec 39
17
+ tools et 6 viewers interactifs.
23
18
 
24
- Chaque PA (Plateforme Agréée) implémente `EInvoiceAdapter`. Les tools MCP appellent l'adapter, jamais l'API directement.
19
+ ## Adapters
25
20
 
26
- ## Configuration
21
+ | | Adapter | Scope | Tools | Base |
22
+ | ------------------------------------------------ | ------------- | ------------------- | ----- | ---------------- |
23
+ | <img src="docs/logos/iopole.svg" height="16"> | **Iopole** | PA française, B2B | 39/39 | BaseAdapter |
24
+ | <img src="docs/logos/storecove.png" height="16"> | **Storecove** | Peppol AP, 40+ pays | 19/39 | BaseAdapter |
25
+ | <img src="docs/logos/superpdp.svg" height="16"> | **Super PDP** | PA française, B2B | 20/39 | AfnorBaseAdapter |
27
26
 
28
- ### Variables d'environnement
27
+ `BaseAdapter` fournit des stubs `NotSupportedError` pour les 45 méthodes de
28
+ l'interface `EInvoiceAdapter`. Les PA françaises avec AFNOR héritent
29
+ d'`AfnorBaseAdapter` (socle
30
+ [AFNOR XP Z12-013](https://norminfo.afnor.org/norme/pr-xp-a00-002/standardisation-api-odpdp/211970))
31
+ qui ajoute les opérations flow. Les autres étendent `BaseAdapter` directement.
32
+
33
+ Le filtrage par `capabilities` assure que le LLM ne voit que les tools supportés
34
+ par l'adapter actif.
35
+
36
+ ## Configuration rapide
29
37
 
30
38
  ```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
39
+ cp .env.example .env
40
+ # Remplir les variables de l'adapter choisi, puis :
41
+ deno task serve # HTTP mode (port 3015)
49
42
  ```
50
43
 
51
- ### MCP config (stdio mode)
44
+ ### MCP config (Claude Desktop / stdio)
52
45
 
53
46
  ```json
54
47
  {
@@ -59,167 +52,133 @@ MCP_AUTH_JWKS_URI=https://auth.example.com/.well-known/jwks.json
59
52
  "env": {
60
53
  "EINVOICE_ADAPTER": "iopole",
61
54
  "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"
55
+ "IOPOLE_CLIENT_ID": "...",
56
+ "IOPOLE_CLIENT_SECRET": "...",
57
+ "IOPOLE_CUSTOMER_ID": "..."
65
58
  }
66
59
  }
67
60
  }
68
61
  }
69
62
  ```
70
63
 
71
- ### HTTP mode
72
-
73
- ```bash
74
- deno run --allow-all server.ts --http --port=3015
75
- ```
64
+ Remplacer `EINVOICE_ADAPTER` par `storecove` ou `superpdp` avec les variables
65
+ correspondantes (voir `.env.example`).
76
66
 
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
67
+ ### Options serveur
83
68
 
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.
69
+ ```
70
+ --http Mode HTTP (default: stdio)
71
+ --port=3015 Port HTTP
72
+ --hostname=localhost Bind address (default: localhost)
73
+ --adapter=iopole Override adapter (default: env EINVOICE_ADAPTER)
74
+ --categories=invoice Filtrer les catégories de tools
75
+ ```
85
76
 
86
- ## Tools (27)
77
+ ## Architecture
87
78
 
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 |
79
+ ```
80
+ ┌───────────────────────────────────────────────┐
81
+ │ 39 MCP Tools (einvoice_*) │
82
+ │ invoice · directory · status · reporting │
83
+ │ webhook · config │
84
+ ├───────────────────────────────────────────────┤
85
+ │ 6 MCP Apps (viewers React) │
86
+ │ invoice · doclist · timeline · card · │
87
+ │ directory-list · action │
88
+ ├───────────────────────────────────────────────┤
89
+ │ EInvoiceAdapter (interface, 45 methods) │
90
+ │ + capabilities → filtrage tools dynamique │
91
+ ├──────────┬────────────────────────────────────┤
92
+ │ BaseAdapter (abstract, NotSupported stubs) │
93
+ ├──────────┼────────────────────────────────────┤
94
+ │ AfnorBase│ Direct │
95
+ │ (AFNOR) │ │
96
+ │ ┌──────┐ │ ┌─────────┐ ┌───────────┐ │
97
+ │ │ SPDP │ │ │ Iopole │ │ Storecove │ │
98
+ │ └──────┘ │ └─────────┘ └───────────┘ │
99
+ └──────────┴────────────────────────────────────┘
100
+ ```
95
101
 
96
- Tous les noms de tools sont préfixés `einvoice_<category>_` (ex: `einvoice_invoice_search`).
102
+ ## Tools
97
103
 
98
- ### Flow generate → preview → emit
104
+ | Catégorie | Tools |
105
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
106
+ | **invoice** (11) | submit, search, get, download, download_readable, files, attachments, download_file, generate_cii, generate_ubl, generate_facturx |
107
+ | **directory** (3) | fr_search, int_search, peppol_check |
108
+ | **status** (2) | send, history |
109
+ | **reporting** (2) | invoice_transaction, transaction |
110
+ | **webhook** (5) | list, get, create, update, delete |
111
+ | **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
112
 
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
113
+ Tous préfixés `einvoice_<category>_`. Chaque tool déclare ses `requires` seuls
114
+ ceux supportés par l'adapter actif sont exposés au LLM.
103
115
 
104
- Les fichiers générés expirent après 10 minutes.
116
+ ### Flow generate preview submit
105
117
 
106
- ## MCP Apps (4 viewers)
118
+ 1. `generate_*` stocke le fichier, retourne `generated_id` + preview viewer
119
+ 2. Le viewer affiche la facture avec bouton "Déposer"
120
+ 3. `submit` consomme le `generated_id` (ou accepte `file_base64` direct)
107
121
 
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 |
122
+ ## Viewers (MCP Apps)
114
123
 
115
- Build des viewers :
124
+ | Viewer | Usage |
125
+ | ------------------- | ---------------------------------------------------------- |
126
+ | **invoice-viewer** | Facture détaillée + actions (accepter, rejeter, déposer) |
127
+ | **doclist-viewer** | Table avec drill-down, recherche, filtres direction/statut |
128
+ | **status-timeline** | Timeline verticale des changements de statut |
129
+ | **directory-card** | Fiche entreprise (SIREN/SIRET, réseaux) |
130
+ | **directory-list** | Résultats annuaire — cartes avec expand, recherche client |
131
+ | **action-result** | Feedback visuel d'action (enroll, register) |
116
132
 
117
133
  ```bash
118
- cd src/ui && node build-all.mjs
134
+ cd src/ui && node build-all.mjs # Rebuild après modification TSX
119
135
  ```
120
136
 
121
- ## Utilisation directe de l'adapter
137
+ ## Ajouter un adapter
122
138
 
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()`
139
+ **PA française avec AFNOR** → `extends AfnorBaseAdapter` (socle AFNOR gratuit,
140
+ override le natif) :
159
141
 
160
142
  ```typescript
161
- import type { EInvoiceAdapter } from "../adapter.ts";
162
-
163
- export class MyPAAdapter implements EInvoiceAdapter {
143
+ export class MyPAAdapter extends AfnorBaseAdapter {
164
144
  readonly name = "my-pa";
165
- // Implémenter les 27 méthodes de l'interface
166
- }
167
- ```
145
+ readonly capabilities = new Set(["emitInvoice", "searchInvoices", ...]);
146
+ private client: MyPAClient;
168
147
 
169
- L'interface `EInvoiceAdapter` est définie dans `src/adapter.ts` — 27 méthodes couvrant factures, annuaire, statuts, reporting et webhooks.
148
+ constructor(client: MyPAClient, afnor: AfnorClient | null) {
149
+ super(afnor); // ou super(null) si pas encore d'AFNOR
150
+ this.client = client;
151
+ }
170
152
 
171
- ## Node.js
153
+ override async generateCII(req) { return this.client.convert(req); }
154
+ // ... override les extras, hériter le reste
155
+ }
156
+ ```
172
157
 
173
- Build single-file CLI via esbuild :
158
+ **PA française sans AFNOR** `extends BaseAdapter` (override toutes les
159
+ méthodes avec l'API native, comme Iopole).
174
160
 
175
- ```bash
176
- ./scripts/build-node.sh
177
- # Produit dist-node/bin/mcp-einvoice.mjs (~1.3MB)
178
- ```
161
+ **Plateforme non-française** → `extends BaseAdapter` directement (comme
162
+ Storecove).
179
163
 
180
- Le script swap `runtime.ts` par `runtime.node.ts` et strip les extensions `.ts` des imports.
164
+ Guide complet : `src/adapters/README.md`.
181
165
 
182
166
  ## Structure
183
167
 
184
168
  ```
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
169
+ server.ts # MCP server (stdio + HTTP)
170
+ src/
171
+ ├── adapter.ts # EInvoiceAdapter (45 methods + capabilities)
172
+ ├── client.ts # Tools registry + capability filtering
173
+ ├── adapters/
174
+ │ ├── base-adapter.ts # BaseAdapter (abstract, NotSupported stubs)
175
+ ├── afnor/ # Socle AFNOR XP Z12-013 (shared)
176
+ │ │ ├── base-adapter.ts # AfnorBaseAdapter (extends BaseAdapter)
177
+ │ │ └── client.ts # AfnorClient (3 flow endpoints)
178
+ ├── shared/oauth2.ts # OAuth2 token provider (shared)
179
+ ├── iopole/ # PA française — extends BaseAdapter
180
+ ├── storecove/ # Peppol AP extends BaseAdapter
181
+ │ └── superpdp/ # PA française extends AfnorBaseAdapter
182
+ ├── tools/ # 39 tools (6 catégories)
183
+ └── ui/ # 6 viewers React (single-file HTML)
216
184
  ```
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)