@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 +129 -170
- package/mcp-einvoice.mjs +3291 -668
- package/package.json +1 -1
- package/ui-dist/action-result/index.html +128 -0
- package/ui-dist/directory-card/index.html +28 -28
- package/ui-dist/directory-list/index.html +128 -0
- package/ui-dist/doclist-viewer/index.html +48 -48
- package/ui-dist/invoice-viewer/index.html +44 -44
- package/ui-dist/status-timeline/index.html +27 -27
package/README.md
CHANGED
|
@@ -1,54 +1,47 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mcp-einvoice
|
|
2
2
|
|
|
3
|
-
MCP
|
|
3
|
+
Serveur MCP pour la facturation électronique — agnostique plateforme via le
|
|
4
|
+
pattern adapter.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
<p align="center">
|
|
7
|
+
<img src="docs/logos/iopole.svg" alt="Iopole" height="40">
|
|
8
|
+
<img src="docs/logos/storecove.png" alt="Storecove" height="40">
|
|
9
|
+
<img src="docs/logos/superpdp.svg" alt="Super PDP" height="40">
|
|
10
|
+
</p>
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
19
|
+
## Adapters
|
|
25
20
|
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
|
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": "
|
|
63
|
-
"IOPOLE_CLIENT_SECRET": "
|
|
64
|
-
"IOPOLE_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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
77
|
+
## Architecture
|
|
87
78
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
102
|
+
## Tools
|
|
97
103
|
|
|
98
|
-
|
|
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
|
-
|
|
101
|
-
|
|
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
|
-
|
|
116
|
+
### Flow generate → preview → submit
|
|
105
117
|
|
|
106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
137
|
+
## Ajouter un adapter
|
|
122
138
|
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
export class MyPAAdapter implements EInvoiceAdapter {
|
|
143
|
+
export class MyPAAdapter extends AfnorBaseAdapter {
|
|
164
144
|
readonly name = "my-pa";
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
```
|
|
145
|
+
readonly capabilities = new Set(["emitInvoice", "searchInvoices", ...]);
|
|
146
|
+
private client: MyPAClient;
|
|
168
147
|
|
|
169
|
-
|
|
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
|
-
|
|
153
|
+
override async generateCII(req) { return this.client.convert(req); }
|
|
154
|
+
// ... override les extras, hériter le reste
|
|
155
|
+
}
|
|
156
|
+
```
|
|
172
157
|
|
|
173
|
-
|
|
158
|
+
**PA française sans AFNOR** → `extends BaseAdapter` (override toutes les
|
|
159
|
+
méthodes avec l'API native, comme Iopole).
|
|
174
160
|
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
164
|
+
Guide complet : `src/adapters/README.md`.
|
|
181
165
|
|
|
182
166
|
## Structure
|
|
183
167
|
|
|
184
168
|
```
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
├──
|
|
188
|
-
├──
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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)
|