# Facturolia MCP server [![tests](https://github.com/toomasgutman-blip/facturolia-mcp/actions/workflows/tests.yml/badge.svg)](https://github.com/toomasgutman-blip/facturolia-mcp/actions/workflows/tests.yml) Let an AI assistant read and check European electronic invoices. Point Claude (or any MCP-compatible client) at a `.pdf` or `.xml` invoice and it answers with the contents in plain language, plus a consistency check against the European standard **EN 16931**. Supports **Factur-X**, **ZUGFeRD**, **XRechnung**, **UBL** and **CII**. ``` > Read ~/Downloads/invoice.pdf Format: Factur-X / CII (EN 16931 (COMFORT) profile) Invoice F-2026-0148 · issued 2026-07-15 · due 2026-08-14 Supplier: Studio Lumiere EURL Customer: Cafe des Arts SARL Total excl. VAT 1240.00 EUR · VAT 248.00 EUR · Total incl. VAT 1488.00 EUR Lines (1): - Consulting : 2 x 620.00 EUR = 1240.00 EUR (VAT 20 %) EN 16931 check: no anomalies found. ``` ## Why this exists A Factur-X invoice is a PDF with structured data hidden inside it. The page a human reads and the data a machine imports are two different things, and they do not always agree. This server exposes both, so an assistant can answer "what is actually in this file?" rather than reading the visible page and hoping. France made structured e-invoicing mandatory for receiving on 1 September 2026, so these files are now arriving in ordinary inboxes. ## Install No dependencies. Python 3.10 or newer is all you need. 1. Download [`facturolia_mcp.py`](facturolia_mcp.py). 2. Get a free API key at [facturolia.fr/en/pricing](https://facturolia.fr/en/pricing). 3. Add it to your client configuration. For Claude Desktop, that is `claude_desktop_config.json`: ```json { "mcpServers": { "facturolia": { "command": "python", "args": ["/absolute/path/to/facturolia_mcp.py"], "env": { "FACTUROLIA_API_KEY": "your-key" } } } } ``` Restart the client. Two tools appear. ## Tools | Tool | What it returns | |---|---| | `read_invoice` | Full contents: parties, dates, lines, VAT breakdown, totals, IBAN, plus the EN 16931 check | | `check_invoice` | The compliance verdict and anomalies only, for "is this invoice correct?" | Both take one argument, `path`, an absolute path to a `.pdf` or `.xml` file. ## Configuration | Variable | Default | Meaning | |---|---|---| | `FACTUROLIA_API_KEY` | required | Your key | | `FACTUROLIA_LANG` | `en` | Response language, `en` or `fr` | | `FACTUROLIA_BASE_URL` | `https://facturolia.fr` | Override for testing. Must be `https://` (plain `http://` only for localhost), otherwise the key is not sent | With `FACTUROLIA_LANG=fr` the answers come back in French, with French date and label conventions. The tool descriptions stay in English so that every client understands them. ## What it does with your file The file is **sent to the Facturolia API** to be analysed. It is processed in memory and discarded immediately, no invoice is stored, and the contents do not appear in the technical logs. The servers are in the European Union. That said, this is **not local processing**. If your policy forbids sending invoices to an external service, use the API yourself inside your own network instead, or do not use this server. Limits: 10 MB per file, `.pdf` and `.xml` only. ## What this is not It reads and checks invoices. It does not issue them, does not transmit them, and is not a compliance solution. In France, sending an invoice legally goes through an accredited platform (*Plateforme Agréée*). This tool sits before and after that step, never in place of it. ## Tests Standard library only, no network needed: ```bash python -m unittest discover -s tests ``` ## Links - Web reader, free and without an account: [facturolia.fr/en](https://facturolia.fr/en) - REST API documentation: [facturolia.fr/en/api](https://facturolia.fr/en/api) ## Licence MIT. See [LICENSE](LICENSE).