Exposes the InvoiceXML API to create, validate, convert, and extract compliant e-invoices across European standards like Factur-X, ZUGFeRD, XRechnung, UBL, and Peppol BIS Billing 3.0. The same .NET codebase runs in two modes: self-hosted with a single API key or as a hosted service with OAuth 2.1 and dynamic client registration. You get typed tools for invoice operations without handling the XML schema complexity yourself. Reach for this when you need AI agents to generate or process e-invoices that meet regulatory requirements in France, Germany, or across PEPPOL networks. The architecture keeps auth cleanly separated so switching between deployment modes is just a config change.
Public tool metadata for what this MCP can expose to an agent.
create_invoiceGenerate a compliant e-invoice from a structured invoice document. Choose the format that matches the buyer's jurisdiction: 'ubl' for Peppol / international Peppol BIS Billing 3.0, 'cii' for generic UN/CEFACT CII XML, 'xrechnung' for German public sector, 'facturx' for French...3 paramsGenerate a compliant e-invoice from a structured invoice document. Choose the format that matches the buyer's jurisdiction: 'ubl' for Peppol / international Peppol BIS Billing 3.0, 'cii' for generic UN/CEFACT CII XML, 'xrechnung' for German public sector, 'facturx' for French...
formatstringubl · cii · xrechnung · facturx · zugferdinvoiceobjectoptionsobjectrender_invoiceRender a plain-XML e-invoice into a human-readable PDF preview. Pick the matching 'format': 'ubl' for UBL 2.1 / Peppol BIS 3.0, 'cii' for UN/CEFACT CII, 'xrechnung' for German XRechnung. The output is a VISUAL PDF only; it does NOT embed the XML. To produce a hybrid Factur-X /...4 paramsRender a plain-XML e-invoice into a human-readable PDF preview. Pick the matching 'format': 'ubl' for UBL 2.1 / Peppol BIS 3.0, 'cii' for UN/CEFACT CII, 'xrechnung' for German XRechnung. The output is a VISUAL PDF only; it does NOT embed the XML. To produce a hybrid Factur-X /...
xmlstringformatstringubl · cii · xrechnungxmlUrlstringlanguagestringEN · DE · FRdefault: ENembed_invoiceCombine an existing PDF and an EN 16931 CII XML into a hybrid PDF/A-3 e-invoice. Pick 'format' = 'facturx' or 'zugferd' for the output branding. The XML MUST be a UN/CEFACT Cross Industry Invoice (CII) document; UBL is not accepted here (convert it first with 'convert_invoice'...5 paramsCombine an existing PDF and an EN 16931 CII XML into a hybrid PDF/A-3 e-invoice. Pick 'format' = 'facturx' or 'zugferd' for the output branding. The XML MUST be a UN/CEFACT Cross Industry Invoice (CII) document; UBL is not accepted here (convert it first with 'convert_invoice'...
xmlstringformatstringfacturx · zugferdpdfUrlstringxmlUrlstringpdfBase64stringextract_invoiceExtract content from a hybrid PDF/A-3 e-invoice (Factur-X or ZUGFeRD). Choose 'target': 'json' for a structured invoice document (fields like seller, buyer, lines, totals), or 'xml' for the raw embedded EN 16931 CII XML. The PDF must contain an embedded XML attachment; if it d...3 paramsExtract content from a hybrid PDF/A-3 e-invoice (Factur-X or ZUGFeRD). Choose 'target': 'json' for a structured invoice document (fields like seller, buyer, lines, totals), or 'xml' for the raw embedded EN 16931 CII XML. The PDF must contain an embedded XML attachment; if it d...
pdfUrlstringtargetstringjson · xmlpdfBase64stringvalidate_pdf_invoiceValidate a hybrid PDF/A-3 e-invoice that has an EN 16931 CII XML embedded inside: Factur-X or ZUGFeRD. Pick 'format' = 'facturx' or 'zugferd' (both run the same validation pipeline; pick the one the user named). Use THIS tool for PDF invoices; for plain XML (UBL / CII / XRechn...3 paramsValidate a hybrid PDF/A-3 e-invoice that has an EN 16931 CII XML embedded inside: Factur-X or ZUGFeRD. Pick 'format' = 'facturx' or 'zugferd' (both run the same validation pipeline; pick the one the user named). Use THIS tool for PDF invoices; for plain XML (UBL / CII / XRechn...
formatstringfacturx · zugferdpdfUrlstringpdfBase64stringconvert_invoiceConvert an e-invoice from one format to another (a deterministic syntax transform, no AI). Set 'sourceFormat' and 'targetFormat', each one of: ubl, cii, xrechnung, facturx, zugferd. Supported conversions: ubl<->cii, xrechnung->ubl/cii, ubl/cii->xrechnung, facturx/zugferd->ubl/...6 paramsConvert an e-invoice from one format to another (a deterministic syntax transform, no AI). Set 'sourceFormat' and 'targetFormat', each one of: ubl, cii, xrechnung, facturx, zugferd. Supported conversions: ubl<->cii, xrechnung->ubl/cii, ubl/cii->xrechnung, facturx/zugferd->ubl/...
xmlstringpdfUrlstringxmlUrlstringpdfBase64stringsourceFormatstringubl · cii · xrechnung · facturx · zugferdtargetFormatstringubl · cii · xrechnung · facturx · zugferdvalidate_xml_invoiceValidate a plain-XML e-invoice against the EN 16931 XSD and Schematron rules. Pick the matching 'format': 'ubl' for UBL 2.1 / Peppol BIS 3.0, 'cii' for UN/CEFACT CII, 'xrechnung' for German XRechnung (CIUS-XR). Use THIS tool for plain XML; for Factur-X / ZUGFeRD hybrid PDFs us...3 paramsValidate a plain-XML e-invoice against the EN 16931 XSD and Schematron rules. Pick the matching 'format': 'ubl' for UBL 2.1 / Peppol BIS 3.0, 'cii' for UN/CEFACT CII, 'xrechnung' for German XRechnung (CIUS-XR). Use THIS tool for plain XML; for Factur-X / ZUGFeRD hybrid PDFs us...
xmlstringformatstringubl · cii · xrechnungxmlUrlstringA Model Context Protocol server that exposes the InvoiceXML API to AI agents. Covers Factur-X, ZUGFeRD, XRechnung, UBL / CII, and Peppol BIS Billing 3.0.
The same codebase runs in two deployment shapes, selected at startup by one environment variable:
| Mode | Who runs it | Auth |
|---|---|---|
| Self-hosted | You, on your own machine or server | A single API key in env or appsettings.json |
| Hosted | InvoiceXML, on its own infrastructure | OAuth 2.1 + Dynamic Client Registration against invoicexml.com |
Both run the same binary; only the configuration differs. The repository is platform-independent — it knows nothing about where or how you host it.
+----------------------+ ProjectReference +----------------------+
| InvoiceXml.Mcp.Core | -------------------> | InvoiceXml.Mcp.Host |
| (SDK: client+tools) | | (the deployable) |
+----------------------+ +----------------------+
InvoiceXml.Mcp.Core is a small, transport-agnostic SDK:
IInvoiceXmlClient — typed client over the public REST APIHttpInvoiceXmlClient — the only implementation; consumes an HttpClient from IHttpClientFactoryInvoiceXmlClientOptions — base URL, timeout (no auth)AddInvoiceXmlMcpCore(IServiceCollection, IConfiguration) — DI entry point; returns the IHttpClientBuilder so the host attaches auth as a DelegatingHandlerThe SDK never sees credentials. The host applies them through the HTTP pipeline. That seam is what lets one codebase serve both deployment modes.
InvoiceXml.Mcp.Host is an ASP.NET Core 10 app:
Mcp:AuthMode (ApiKey or OAuth) at startupDelegatingHandler onto the Core HTTP client via AddHostAuth(...)POST /, a human-friendly welcome page at GET /, and /healthAdding a new auth mode = one arm in AuthExtensions.cs plus a small folder under
Auth/<Mode>/. Adding a new tool = one [McpServerTool] class. Nothing else changes.
invoicexml-mcp/
├── src/
│ ├── InvoiceXml.Mcp.Core/ # the SDK: client, models, tools
│ │ ├── Enums/ Interfaces/ Models/ Options/ Services/ Tools/ Extensions/
│ └── InvoiceXml.Mcp.Host/ # the deployable host
│ ├── Auth/{ApiKey,OAuth}/ # the two auth modes
│ ├── Configuration/
│ ├── Program.cs
│ └── appsettings.json # safe defaults, no secrets
├── tests/
│ ├── InvoiceXml.Mcp.Core.Tests/
│ └── InvoiceXml.Mcp.Host.Tests/
├── Directory.Build.props # repo-wide MSBuild defaults
├── Directory.Packages.props # Central Package Management
├── global.json # pins the .NET SDK
└── InvoiceXml.Mcp.slnx
You need a .NET 10 SDK and an InvoiceXML API key.
# 1. Provide your API key (pick one):
# A. dotnet user-secrets (recommended — kept outside the repo)
dotnet user-secrets --project src/InvoiceXml.Mcp.Host set "Mcp:ApiKey:Value" "your-key"
# B. environment variable
$env:INVOICEXML_API_KEY = "your-key"
# 2. Run
dotnet run --project src/InvoiceXml.Mcp.Host
GET http://localhost:5004/ shows a welcome page in a browser; the MCP endpoint is
POST http://localhost:5004/; GET /health returns { "status": "ok" }.
{
// Required in OAuth mode. The public origin where this MCP server is reachable.
// Used in the protected-resource metadata response.
"McpUri": "https://mcp.example.com",
"InvoiceXml": {
"BaseUrl": "https://api.invoicexml.com", // override for staging / local
"Timeout": "00:01:40"
},
"Mcp": {
"AuthMode": "ApiKey", // "ApiKey" | "OAuth"
"ApiKey": {
"Value": "" // ApiKey mode: NEVER commit a real key
},
"OAuth": {
"AuthorizationServer": "https://invoicexml.com",
"ScopesSupported": [ "api_token.read" ]
},
"FileInput": { // limits for the URL-fetch input mode
"MaxFileSizeBytes": 5242880,
"FetchTimeout": "00:00:30"
}
}
}
Environment variable equivalents (double underscore = nesting):
| Variable | Maps to |
|---|---|
INVOICEXML_API_KEY | Mcp:ApiKey:Value (friendly alias) |
Mcp__ApiKey__Value | Mcp:ApiKey:Value |
Mcp__AuthMode | Mcp:AuthMode (ApiKey or OAuth) |
Mcp__OAuth__AuthorizationServer | Mcp:OAuth:AuthorizationServer |
McpUri | McpUri (root-level) |
InvoiceXml__BaseUrl | InvoiceXml:BaseUrl |
When Mcp:AuthMode=OAuth the host stops accepting a static API key and instead:
WWW-Authenticate: Bearer resource_metadata="…" for any
POST / that has no Bearer token.GET /.well-known/oauth-protected-resource pointing MCP clients at
invoicexml.com as the authorization server.The dance an MCP client performs:
client → MCP POST / → 401 + resource_metadata
client → /.well-known/oauth-protected-resource → { authorization_servers: [invoicexml.com] }
client → invoicexml.com/.well-known/oauth-authorization-server
→ { authorize, token, register endpoints }
client → invoicexml.com/oauth/register → client_id + client_secret (DCR)
client → invoicexml.com/oauth/authorize → user consents, gets code
client → invoicexml.com/oauth/token → access_token (= user's API key)
client → MCP POST / + Authorization: Bearer → 200, tool call flows through
The host is a standard ASP.NET Core app — run it however you run .NET services (systemd, a container, a PaaS, etc.; the repo doesn't prescribe one):
dotnet publish src/InvoiceXml.Mcp.Host -c Release -o ./publish
# then run ./publish/InvoiceXml.Mcp.Host on your host
Set configuration via environment variables on the host (never commit secrets):
ASPNETCORE_ENVIRONMENT=ProductionMcp__AuthMode=ApiKey (or OAuth)Mcp__ApiKey__Value=… / INVOICEXML_API_KEY=… (ApiKey mode)McpUri=https://your-public-url and Mcp__OAuth__AuthorizationServer=https://invoicexml.com (OAuth mode)Terminate TLS at your reverse proxy / load balancer and forward to the host's HTTP port. The server is stateless, so you can run multiple instances behind a load balancer.
MIT — see LICENSE.
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp