@casys/mcp-einvoice 0.1.0

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 ADDED
@@ -0,0 +1,225 @@
1
+ # @casys/mcp-einvoice
2
+
3
+ MCP server for French e-invoicing — PA-agnostic via the adapter pattern.
4
+
5
+ ## Architecture
6
+
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
+ ```
23
+
24
+ Chaque PA (Plateforme Agréée) implémente `EInvoiceAdapter`. Les tools MCP appellent l'adapter, jamais l'API directement.
25
+
26
+ ## Configuration
27
+
28
+ ### Variables d'environnement
29
+
30
+ ```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
49
+ ```
50
+
51
+ ### MCP config (stdio mode)
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "einvoice": {
57
+ "command": "deno",
58
+ "args": ["run", "--allow-all", "server.ts"],
59
+ "env": {
60
+ "EINVOICE_ADAPTER": "iopole",
61
+ "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"
65
+ }
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### HTTP mode
72
+
73
+ ```bash
74
+ deno run --allow-all server.ts --http --port=3015
75
+ ```
76
+
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
83
+
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.
85
+
86
+ ## Tools (27)
87
+
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 |
95
+
96
+ Tous les noms de tools sont préfixés `einvoice_<category>_` (ex: `einvoice_invoice_search`).
97
+
98
+ ### Flow generate → preview → emit
99
+
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
+
104
+ Les fichiers générés expirent après 10 minutes.
105
+
106
+ ## MCP Apps (4 viewers)
107
+
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 |
114
+
115
+ Build des viewers :
116
+
117
+ ```bash
118
+ cd src/ui && node build-all.mjs
119
+ ```
120
+
121
+ ## Utilisation directe de l'adapter
122
+
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()`
159
+
160
+ ```typescript
161
+ import type { EInvoiceAdapter } from "../adapter.ts";
162
+
163
+ export class MyPAAdapter implements EInvoiceAdapter {
164
+ readonly name = "my-pa";
165
+ // Implémenter les 27 méthodes de l'interface
166
+ }
167
+ ```
168
+
169
+ L'interface `EInvoiceAdapter` est définie dans `src/adapter.ts` — 27 méthodes couvrant factures, annuaire, statuts, reporting et webhooks.
170
+
171
+ ## Node.js
172
+
173
+ Build single-file CLI via esbuild :
174
+
175
+ ```bash
176
+ ./scripts/build-node.sh
177
+ # Produit dist-node/bin/mcp-einvoice.mjs (~1.3MB)
178
+ ```
179
+
180
+ Le script swap `runtime.ts` par `runtime.node.ts` et strip les extensions `.ts` des imports.
181
+
182
+ ## Structure
183
+
184
+ ```
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
216
+ ```
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)