1. Overview

The server provides three tools and one resource that AI agents can call through the Model Context Protocol.

ScenarioTool / Resource
Check an invoice before sendingvalidate_invoice
Read XML data from a ZUGFeRD PDFextract_xml
Check whether PDF and XML matchcheck_consistency
Query available formats and rule setsvalidation://rules
Every response is structured JSON. No free text — each error contains a rule ID, the affected field, an error message, an actionable fix suggestion and an XPath.

2. Architecture & Data Flow

AI agent │ │ MCP message (JSON-RPC over stdio) ▼ ┌─────────────────────────────────────────┐ │ zugferd-mcp-client (npm, local) │ │ │ │ validate_invoice · extract_xml │ │ check_consistency │ │ │ │ │ HTTPS REST request │ │ ▼ │ │ ZUGFeRD Validator API (hosted) │ │ api.zugferd-validator.de │ │ Auth: X-Api-Key │ │ │ │ │ Base64 → Mustang + KoSIT (parallel) │ │ ▼ │ │ Report parser + fix-suggestions DB │ └─────────────────┬───────────────────────┘ │ Structured JSON ▼ AI agent receives result

Flow for validate_invoice

1
MCP client receives the call — Base64 file + parameters from the AI agent
2
HTTPS request to the API — POST /v1/validate with X-Api-Key header
3
Auth & rate limit — the API checks the key and the tier's monthly limit
4
Dual validation (parallel) — Mustang CLI (ZUGFeRD/Factur-X) and the KoSIT validation tool (XRechnung + EN 16931 CII) run at the same time (max. 30s)
5
Consolidate results — errors from both engines are merged and deduplicated; fix suggestions are added
6
JSON result — the API responds, the MCP client forwards it to the AI agent

3. Validation Engines

Every request is checked by two engines at once. The results are consolidated, deduplicated and returned.

EngineVersionCovered formats
Mustang Project v2.22.0 ZUGFeRD 1.0–2.4, Factur-X 1.0, XRechnung (general)
KoSIT validation tool v1.6.2 XRechnung 3.0.2 (CII + UBL), EN 16931 CII/UBL (plain), Factur-X 1.07.3 / 1.08 (all profiles)
Consolidated response: errors from both engines appear in the same errors list. Duplicates (same rule ID + message) are removed automatically. KoSIT errors are only included when a matching validation scenario was detected — for unknown GuidelineIDs, Mustang runs alone.

4. Installation & Configuration

1
Get an API key
# Register for free:
https://zugferd-validator.de/portal
2
Install the MCP client
npm install -g zugferd-mcp-client
3
Configure in your MCP client
// mcp_config.json (path varies by client)
{
  "mcpServers": {
    "zugferd": {
      "command": "zugferd-mcp-client",
      "env": {
        "ZUGFERD_API_KEY": "zv_your_key_here"
      }
    }
  }
}

Direct REST API

The API can also be called directly, without the MCP client:

# Example: validation via curl
curl -X POST https://api.zugferd-validator.de/v1/validate \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: zv_your_key_here" \
  -d '{"file_content":"<base64>","file_type":"xml"}'

Environment variables (MCP client)

VariableDescriptionDefault
ZUGFERD_API_KEYAPI key from the portal– (required)
ZUGFERD_API_URLAPI base URLhttps://api.zugferd-validator.de

5. Tools

validate_invoice TOOL

Validates an e-invoice (ZUGFeRD/Factur-X PDF or XRechnung XML) against EN 16931 and the German extensions. Returns structured errors, warnings and fix suggestions.

Input schema

file_content * string Base64-encoded content of the PDF or XML file. Data URL prefixes (data:application/pdf;base64,…) are removed automatically.
file_type * enum "pdf" for ZUGFeRD/Factur-X PDFs · "xml" for plain XRechnung/CII XML files
profile enum? Optional profile hint. If it differs from the detected profile, a warning with rule_id: "PROFILE_MISMATCH" is generated.
Values: minimum · basic_wl · basic · en16931 · extended · xrechnung

Output schema

{
  "valid":    true,
  "format":   "ZUGFeRD 2.x",
  "profile":  "EN16931",
  "summary":  "No issues found",
  "errors":   [],
  "warnings": [],
  "notices":  [],
  "metadata": {
    "invoice_number": "RE-2026-001",
    "issue_date":     "2026-04-01",
    "seller":         "Musterfirma GmbH",
    "buyer":          "Beispiel AG",
    "total_amount":   "1190.00",
    "currency":       "EUR"
  }
}
{
  "valid":   false,
  "format":  "ZUGFeRD 2.x",
  "profile": "EN16931",
  "summary": "2 errors, 1 warning found",
  "errors": [
    {
      "severity":       "error",
      "rule_id":        "BR-DE-15",
      "field":          "BT-10",
      "message":        "The buyer reference / routing ID (BT-10) must be provided.",
      "fix_suggestion": "Add the buyer reference / routing ID (BT-10) in 'ram:ApplicableHeaderTradeAgreement/ram:BuyerReference'.",
      "xpath":          "//ram:ApplicableHeaderTradeAgreement/ram:BuyerReference"
    }
  ],
  "warnings": [
    {
      "severity":       "warning",
      "rule_id":        "BR-CL-10",
      "field":          "BT-81",
      "message":        "The payment means code must come from UNTDID 4461.",
      "fix_suggestion": "Use e.g. '58' for SEPA credit transfer or '59' for SEPA direct debit.",
      "xpath":          "//ram:SpecifiedTradeSettlementPaymentMeans/ram:TypeCode"
    }
  ]
}

Output fields

FieldTypeRequiredDescription
validbooleanYestrue when not a single error was found
formatstringNoDetected format, e.g. "ZUGFeRD 2.x", "CII EN16931", "XRechnung 3.0"null when no XML can be extracted
profilestringNoDetected profile in uppercase, e.g. "EN16931", "XRECHNUNG"null when no XML can be extracted
summarystringYesHuman-readable summary, e.g. "2 errors, 1 warning found"
errorsarrayYesValidation errors — these make the invoice invalid
warningsarrayYesWarnings — the invoice can still be valid
noticesarrayNoInformational notices with no impact on validity
metadataobjectNoExtracted invoice data — present for PDFs when the embedded XML was read successfully, and always for file_type: "xml"
extract_xml TOOL

Extracts the embedded XML document from a ZUGFeRD/Factur-X PDF. Returns the full XML content as a string, together with the detected format and profile.

Input

pdf_content * string Base64-encoded content of the ZUGFeRD/Factur-X PDF file.

Output

{
  "xml_content": "<?xml version='1.0' encoding='UTF-8'?>\n<rsm:CrossIndustryInvoice ...>...</rsm:CrossIndustryInvoice>",
  "format":      "ZUGFeRD 2.x",
  "profile":     "EN16931"
}
The extracted xml_content can be passed directly (after Base64 encoding) to validate_invoice with file_type: "xml".
check_consistency TOOL

Checks whether the human-readable data in the PDF (invoice number, date, total amount) matches the machine data stored in the XML attachment. Reveals tampering or data-entry errors.

Input

pdf_content * string Base64-encoded content of the ZUGFeRD/Factur-X PDF file.

Output

{
  "consistent":    true,
  "discrepancies": []
}
{
  "consistent":    false,
  "discrepancies": [
    {
      "field":     "total_amount",
      "pdf_value": "1190.00",
      "xml_value": "1180.00",
      "message":   "The total amount in the PDF ('1190.00') differs from the one in the XML ('1180.00')."
    }
  ]
}

Checked fields & tolerances

FieldDetection pattern in the PDFTolerance
invoice_numberRechnungsnummer:, Rechnung Nr., Invoice No.Case, spaces and hyphens ignored
issue_dateRechnungsdatum:, Datum:, Invoice Date:None — date formats are normalized to ISO 8601
total_amountGesamtbetrag:, Rechnungsbetrag:, Total:±0.01 EUR (rounding differences)
Text detection relies on the machine-readable PDF text. Scanned PDFs without an OCR layer are not supported.
create_invoice TOOL

Builds a valid e-invoice from structured data — either as a ZUGFeRD PDF (PDF/A-3 with embedded EN 16931 CII XML) or as plain XRechnung XML (CII with the XRechnung 3.0 CIUS and routing ID for B2G). Multiple line items, all VAT categories (S/Z/E/AE), allowances/charges, payment details. REST: POST /v1/create. Stateless — nothing is stored. Amounts in cents, date as YYYY-MM-DD.

Input (excerpt)

format *stringzugferd (PDF) or xrechnung (XML)
document_typestringDocument kind, default invoice: credit_note (credit note / cancellation), corrected, self_billed, prepayment (down payment), partial (partial invoice). Raw override via type_code.
preceding_invoiceobjectReference to the original invoice { number, date } — for cancellations/corrections (BT-25/26)
number, date *stringDocument number and date (YYYY-MM-DD)
seller, buyer *objectParties (name, street, zip, city, country, vat_id, email …)
lines *arrayLine items: name, quantity, unit_net_price_cents, vat_category, vat_rate
allowances_chargesarrayAllowances/charges at document level
buyer_referencestringRouting ID (BT-10) — required for xrechnung
payment_terms, due_date, payment_meansstring/objectPayment terms, due date, IBAN/BIC
seller_logostringLogo Base64 (PNG/JPG) — Automate/Scale tiers only
self_checkbooleanCheck immediately against EN 16931 (slower). Default false.

Output

{
  "format":     "zugferd",
  "profile":    "EN16931",
  "pdf_base64": "JVBERi0xLjc…",
  "xml":        "<?xml version=\"1.0\"…",
  "branding":   "free_footer"
}
Self-check is decoupled: by default the invoice comes back immediately. You obtain the conformity proof in a second step via validate_invoice on the returned pdf_base64 or xml — or set self_check: true for a single round trip. Branding (footer on the Check tier / white-label from the Automate tier) is determined server-side from the tier. Separate weekly quota: Check 1, Automate 20, Scale unlimited.
Sandbox key (zv_test_…, via GET /v1/keys/me): for free integration without using the live quota. Created invoices carry a tiled "DEMO" watermark on every page plus an XML marker — fully testable, but worthless as a real invoice. 100/day, 3/minute; counted separately from the live quota.

6. Resource: validation_rules

Returns the server's current rule set: supported formats, profiles and the validation engine in use.

URI: validation://rules

{
  "supported_formats": [
    "ZUGFeRD 1.0", "ZUGFeRD 2.0", "ZUGFeRD 2.1", "ZUGFeRD 2.2",
    "ZUGFeRD 2.3", "ZUGFeRD 2.x / Factur-X 1.0x",
    "XRechnung 1.2", "XRechnung 2.0", "XRechnung 2.3", "XRechnung 3.0"
  ],
  "supported_profiles": [
    "minimum", "basic_wl", "basic", "en16931", "extended", "xrechnung"
  ],
  "validation_engines": [
    "Mustang Project v2.22.0",
    "KoSIT Validierungstool v1.6.2 (XRechnung 3.0.2 + EN 16931 CII)"
  ],
  "last_updated":      "2026-04-08"
}

7. Error Handling

On failure, all tools return a JSON object with an error field. There is never unstructured error output.

{
  "error":   "Short error category",
  "details": "Detailed description with a concrete hint on how to fix it."
}
errorTrigger
"Fehlender Parameter"Required field not provided
"Ungültiger Parameter"Wrong value for file_type
"Ungültiger Base64-Input"No valid Base64 string provided
"Validierungsfehler"Mustang CLI could not start (e.g. Java missing) or timed out after 30s
"XML-Extraktion fehlgeschlagen"No XML file found in the PDF attachment (for extract / consistency). For validate, a notice with rule_id: "NO_EMBEDDED_XML" is returned instead and valid: true is set
"PDF-Lesefehler"The PDF cannot be read
"XML-Parsing-Fehler"The extracted XML is not valid XML
"Interner Fehler"Unexpected runtime error
Timeout: both validation engines run in parallel and are aborted after 30 seconds each. If Mustang fails, "error": "Validierungsfehler" is returned. A KoSIT timeout is silently ignored — Mustang results are kept.

8. Common Data Types

ValidationIssue

Used in the errors, warnings and notices arrays of validate_invoice.

FieldTypeRequiredDescription
severity"error" | "warning" | "notice"YesSeverity of the finding
rule_idstringYesRule ID, e.g. "BR-DE-1", "BR-CL-10". Value "UNKNOWN" for XSD schema violations (KoSIT) or when no rule ID can be determined
fieldstringNoAffected BT field, e.g. "BT-10"
messagestringYesError message in German
fix_suggestionstringNoConcrete fix hint with an XML example
xpathstringNoXPath to the affected XML element

InvoiceMetadata

Optional field in the result of validate_invoice (only for file_type: "xml").

FieldTypeDescription
invoice_numberstring?Invoice number (BT-1)
issue_datestring?Invoice date, ISO 8601, e.g. "2026-04-01"
sellerstring?Seller name (BT-27)
buyerstring?Buyer name (BT-44)
total_amountstring?Total amount as a decimal string, e.g. "1190.00"
currencystring?ISO 4217 currency code, e.g. "EUR"

9. Supported Formats & Profiles

Formats

FormatStandardNote
ZUGFeRD 1.0ZUGFeRD 1.0 / GEFEGOlder version, limited profile support
ZUGFeRD 2.0FeRD 2.0First CII-based version
ZUGFeRD 2.1Factur-X 1.0 (FR)Technically identical to Factur-X 1.0
ZUGFeRD 2.2Factur-X 1.0.05Minor corrections
ZUGFeRD 2.3Factur-X 1.0.06Version before 2.4
ZUGFeRD 2.x / Factur-X 1.0xEN 16931 + D16BCurrent main version (2026) — the API returns "ZUGFeRD 2.x"
XRechnung 1.2XRechnung 1.2Older XRechnung version
XRechnung 2.xXRechnung 2.0–2.3Various intermediate versions
XRechnung 3.0XRechnung 3.0Current XRechnung version

Profiles (ZUGFeRD/Factur-X)

Profile IDDisplay nameTypical use
minimumMINIMUMSimple machine processing
basic_wlBASIC-WLWithout line-item detail
basicBASICStandard invoices
en16931EN 16931 (COMFORT)Public authorities, PEPPOL
extendedEXTENDEDComplex B2B processes
xrechnungXRECHNUNGGerman public administration

10. Rule Set & Fix Suggestions

The server contains a database of fix suggestions for 63 rule categories. Errors from both validation engines (Mustang + KoSIT) are consolidated — when a known rule ID is found, the fix suggestion is attached automatically.

BR-DE rules 26 rules

German extensions — mandatory for XRechnung-compliant invoices.

Rule IDFieldShort description
BR-DE-1BG-16PAYMENT INSTRUCTIONS (BG-16) missing
BR-DE-2BG-6SELLER CONTACT (BG-6)
BR-DE-3BT-37Seller city (BT-37)
BR-DE-4BT-38Seller post code (BT-38)
BR-DE-5BT-41Seller contact point (BT-41)
BR-DE-6BT-42Seller phone number (BT-42)
BR-DE-7BT-43Seller email (BT-43)
BR-DE-8BT-52Buyer city (BT-52)
BR-DE-9BT-53Buyer post code (BT-53)
BR-DE-10BT-77Deliver-to city (BT-77)
BR-DE-11BT-78Deliver-to post code (BT-78)
BR-DE-12Removed in the current XRechnung release
BR-DE-13Removed in the current XRechnung release
BR-DE-14BT-119VAT rate (BT-119)
BR-DE-15BT-10Buyer reference / routing ID (BT-10)
BR-DE-16BT-31Seller VAT ID / tax number
BR-DE-17BT-3Invalid invoice type code (BT-3)
BR-DE-18BT-20Payment discount terms (BT-20) in the wrong format
BR-DE-19Removed in the current XRechnung release
BR-DE-20Removed in the current XRechnung release
BR-DE-21BT-24Specification identifier (BT-24) not XRechnung-compliant
BR-DE-22Attachment file names not unique
BR-DE-23Removed in the current XRechnung release
BR-DE-24Removed in the current XRechnung release
BR-DE-25Removed in the current XRechnung release
BR-DE-26BT-3Correction invoice without a reference invoice (BG-3)

EN 16931 core rules (BR-*) 10 rules

Rule IDFieldShort description
BR-1BT-24Specification identifier (BT-24)
BR-2BT-1Invoice number (BT-1)
BR-3BT-2Invoice issue date (BT-2)
BR-4BT-3Invoice type code (BT-3)
BR-5BT-5Currency code (BT-5)
BR-6BT-27Seller name (BT-27)
BR-7BT-44Buyer name (BT-44)
BR-8BG-5Seller postal address (BG-5)
BR-9BG-5Seller country code (BT-40)
BR-10BG-8Buyer postal address (BG-8)

Calculation rules (BR-CO-*) & code-list rules (BR-CL-*) 8 rules

Rule IDShort description
BR-CO-3Tax point date and tax point date code are mutually exclusive
BR-CO-9Seller VAT ID without a country prefix
BR-CO-10Sum of net line amounts does not match
BR-CO-13Total amount excluding VAT calculated incorrectly
BR-CL-10Invalid schemeID (not from ISO 6523)
BR-CL-16Invalid payment means code (not from UNTDID 4461)
BR-CL-17Invalid VAT category at line level
BR-CL-18Invalid VAT category at document level

Tax category rules (BR-S/Z/E/AE-*) 4 rules

Rule IDShort description
BR-S-1Tax amount given for the standard rate (S)
BR-Z-1Tax amount for the zero rate (Z) = 0
BR-E-1Tax amount for tax exemption (E) = 0
BR-AE-1Tax amount for reverse charge (AE) = 0

11. Usage Examples

Example 1: Validate an XRechnung XML

{
  "tool": "validate_invoice",
  "arguments": {
    "file_content": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
    "file_type":   "xml",
    "profile":     "xrechnung"
  }
}
{
  "valid":   true,
  "format":  "XRechnung 3.0",
  "profile": "XRECHNUNG",
  "summary": "No issues found",
  "errors":  [],
  "warnings": [],
  "metadata": {
    "invoice_number": "INV-2026-0042",
    "issue_date":     "2026-04-07",
    "seller":         "Tech GmbH",
    "buyer":          "Bundesbehörde X",
    "total_amount":   "5950.00",
    "currency":       "EUR"
  }
}

Example 2: Faulty invoice with a fix suggestion

{
  "tool": "validate_invoice",
  "arguments": {
    "file_content": "JVBERi0xLjQK...",
    "file_type":   "pdf"
  }
}
{
  "valid":   false,
  "format":  "ZUGFeRD 2.x",
  "profile": "EN16931",
  "summary": "1 error found",
  "errors": [{
    "severity":       "error",
    "rule_id":        "BR-DE-23",
    "field":          "BT-10",
    "message":        "The buyer reference (BT-10) must be provided for XRechnung.",
    "fix_suggestion": "Add 'ram:BuyerReference', e.g. '04011000-1234-34' for public authorities.",
    "xpath":          "//ram:ApplicableHeaderTradeAgreement/ram:BuyerReference"
  }],
  "warnings": []
}

Example 3: Extract and validate XML

// Step 1 — extract the XML from the PDF
{ "tool": "extract_xml", "arguments": { "pdf_content": "JVBERi0x..." } }

// Step 2 — validate the extracted XML (passed Base64-encoded)
{ "tool": "validate_invoice", "arguments": { "file_content": "<base64 of xml_content>", "file_type": "xml" } }

Example 4: Consistency check

{
  "tool": "check_consistency",
  "arguments": { "pdf_content": "JVBERi0xLjQK..." }
}
{
  "consistent":    false,
  "discrepancies": [{
    "field":     "total_amount",
    "pdf_value": "1190.00",
    "xml_value": "1180.00",
    "message":   "The total amount in the PDF ('1190.00') differs from the one in the XML ('1180.00')."
  }]
}

Example 5: Plain PDF without embedded XML

A regular PDF invoice without a ZUGFeRD/Factur-X attachment returns valid: true with an informational notice — not an error, but a hint that no structured data could be checked.

{
  "tool": "validate_invoice",
  "arguments": {
    "file_content": "JVBERi0xLjQK...",
    "file_type":   "pdf"
  }
}
{
  "valid":    true,
  "format":   null,
  "profile":  null,
  "summary":  "2 notices found",
  "errors":   [],
  "warnings": [],
  "notices": [
    {
      "severity": "notice",
      "rule_id":  "UNKNOWN",
      "message":  "XML could not be extracted"
    },
    {
      "severity": "notice",
      "rule_id":  "NO_EMBEDDED_XML",
      "message":  "Kein eingebettetes XML gefunden. Die PDF ist möglicherweise keine ZUGFeRD/Factur-X Rechnung."
    }
  ]
}

12. Limits & Known Constraints

ConstraintDetails
TimeoutMustang CLI is aborted server-side after 30 seconds. Very large or corrupt files can trigger this timeout.
Rate limitValidation: Check 20/week · Automate 500/week · Scale unlimited. Creation (separate quota): Check 1/week · Automate 20/week · Scale unlimited. Sandbox creation: 100/day, max. 3/minute. On exceeding the limit: HTTP 429.
PDF OCRcheck_consistency only evaluates machine-readable PDF text. Scanned PDFs without an OCR layer are not supported.
Metadata for PDFsvalidate_invoice also extracts metadata for PDFs, provided an embedded XML is present and readable. For plain PDFs without XML, this field is missing.
Consistency checkOnly three fields are compared (number, date, amount). Addresses, tax numbers and line-item details are not reconciled.
Unknown rule IDsIf a rule ID is missing from the fix-suggestions DB, fix_suggestion stays empty. The message is still returned.
File sizeNo explicit size limit, but very large PDFs (>50 MB) can lead to a timeout.

13. Changelog

June 2026 — Invoice creation

  • New tool create_invoice / POST /v1/create: build valid e-invoices from structured data — as a ZUGFeRD PDF (PDF/A-3) or plain XRechnung XML (with routing ID for B2G).
  • Multiple line items, all VAT categories (S/Z/E/AE), allowances/charges, payment details, due date.
  • Document types: invoice, credit note/cancellation, correction, self-billing, down-payment and partial invoice — with a reference to the original invoice.
  • Tier-dependent branding (footer on the Check tier / white-label from the Automate tier with an optional logo); separate weekly quota, kept apart from validation.
  • Sandbox/test keys (zv_test_…): free integration with a "DEMO" watermark, without using up the live quota.

April 2026 — Initial release

  • Validation against EN 16931 (validate_invoice) for ZUGFeRD/Factur-X PDF and XRechnung XML, with concrete fix suggestions.
  • XML extraction (extract_xml) and PDF↔XML consistency check (check_consistency).
  • MCP client for Claude & other AI agents; Mustang and KoSIT engines.