InvoiceXML
InvoiceXML brings e-invoice compliance to your AI agent. Create, validate, convert, render, and extract structured invoices across UBL (Peppol BIS Billing 3.0, used worldwide), CII, Factur-X, ZUGFeRD, and XRechnung, all checked against the EN 16931 standard and official Schematron rules. Ask your assistant to generate a compliant invoice, validate one for errors, or convert between formats, with n
README
InvoiceXML MCP Server
A 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.
Architecture
+----------------------+ 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 anHttpClientfromIHttpClientFactoryInvoiceXmlClientOptions— base URL, timeout (no auth)AddInvoiceXmlMcpCore(IServiceCollection, IConfiguration)— DI entry point; returns theIHttpClientBuilderso the host attaches auth as aDelegatingHandler
The 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:
- Reads
Mcp:AuthMode(ApiKeyorOAuth) at startup - Wires the matching
DelegatingHandleronto the Core HTTP client viaAddHostAuth(...) - Serves the MCP endpoint at
POST /, a human-friendly welcome page atGET /, and/health
Adding 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.
Repository layout
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
Running locally
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" }.
Configuration
{
// 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 |
OAuth mode
When Mcp:AuthMode=OAuth the host stops accepting a static API key and instead:
- Returns 401 with
WWW-Authenticate: Bearer resource_metadata="…"for anyPOST /that has no Bearer token. - Serves
GET /.well-known/oauth-protected-resourcepointing MCP clients atinvoicexml.comas the authorization server. - Forwards the inbound Bearer token verbatim on every outbound call to the InvoiceXML API (the API is the source of truth for token validity; the MCP server does not validate tokens locally).
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
Deployment
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(orOAuth)Mcp__ApiKey__Value=…/INVOICEXML_API_KEY=…(ApiKey mode)McpUri=https://your-public-urlandMcp__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.
License
MIT — see LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.