invoice_convert
Convert ZUGFeRD and XRechnung invoices between different profiles and syntaxes, including CII↔UBL conversion, with data loss control for profile downgrades.
Instructions
Convert a ZUGFeRD or XRechnung invoice to a different profile or syntax. Supports ZUGFeRD profile upgrades and downgrades, ZUGFeRD ↔ XRechnung conversion, and CII ↔ UBL syntax transformation (XRechnung only). Profile downgrades may result in data loss; set allow_data_loss=True to permit this.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| xml_content | No | ||
| xml_base64 | No | ||
| target_profile | Yes | ||
| target_syntax | No | CII | |
| allow_data_loss | No |
Implementation Reference
- The MCP handler function for invoice_convert. It validates input, resolves XML, and returns a stub 'not yet implemented' response. The conversion pipeline is marked as TODO.
async def handle_invoice_convert(arguments: dict[str, Any]) -> list[types.TextContent]: """MCP handler for invoice_convert.""" try: params = InvoiceConvertInput.model_validate(arguments) except Exception as exc: return [types.TextContent(type="text", text=json.dumps(format_error(str(exc))))] try: resolve_xml_input(params.xml_content, params.xml_base64) except (ValueError, EInvoicingError) as exc: return [types.TextContent(type="text", text=json.dumps(format_error(str(exc))))] # TODO: implement conversion pipeline # Steps: # 1. Parse source XML → ZUGFeRDInvoice model (via invoice_parse logic) # 2. Detect source profile and syntax # 3. Validate conversion path (upgrade vs. downgrade, data loss check) # 4. Apply profile-specific field pruning for downgrades # 5. Update GuidelineID URN to target profile # 6. Re-serialise to CII or UBL XML # 7. Collect data_loss_warnings and conversion_notes # [NEED: define conversion matrix (which fields are mandatory per profile)] # [NEED: verify if mcp-einvoicing-core provides a profile compatibility matrix] return [ types.TextContent( type="text", text=json.dumps( { "error": "Conversion not yet implemented.", "target_profile": params.target_profile, "target_syntax": params.target_syntax, "hint": "TODO: implement conversion pipeline", } ), ) ] - Input schema (InvoiceConvertInput): xml_content, xml_base64, target_profile, target_syntax, allow_data_loss.
class InvoiceConvertInput(BaseModel): """Input schema for invoice_convert.""" xml_content: str | None = Field(None, description="Raw XML string of the source invoice.") xml_base64: str | None = Field(None, description="Base64-encoded XML bytes.") target_profile: str = Field( ..., description=( "Target profile. One of: MINIMUM, BASIC_WL, BASIC, EN_16931, EXTENDED, XRECHNUNG." ), ) target_syntax: str = Field( "CII", description="Target syntax: 'CII' or 'UBL'. UBL is only valid for XRECHNUNG.", ) allow_data_loss: bool = Field( False, description=( "If True, allow profile downgrades that discard data. " "Discarded fields are listed in the output. " "If False and data loss would occur, the conversion is rejected." ), ) - Output schema (InvoiceConvertOutput): target xml, source/target profile+syntax, data_loss_warnings, conversion_notes.
class InvoiceConvertOutput(BaseModel): """Output schema for invoice_convert.""" xml_content: str | None = None source_profile: str source_syntax: str target_profile: str target_syntax: str data_loss_warnings: list[str] = Field( default_factory=list, description="Fields discarded during profile downgrade.", ) conversion_notes: list[str] = Field(default_factory=list) - mcp_einvoicing_de/tools/invoice_convert.py:70-93 (registration)TOOL_INVOICE_CONVERT: types.Tool object defining name 'invoice_convert', description, and JSON Schema inputSchema.
TOOL_INVOICE_CONVERT = types.Tool( name="invoice_convert", description=( "Convert a ZUGFeRD or XRechnung invoice to a different profile or syntax. " "Supports ZUGFeRD profile upgrades and downgrades, ZUGFeRD ↔ XRechnung conversion, " "and CII ↔ UBL syntax transformation (XRechnung only). " "Profile downgrades may result in data loss; set allow_data_loss=True to permit this." ), inputSchema={ "type": "object", "required": ["target_profile"], "properties": { "xml_content": {"type": "string"}, "xml_base64": {"type": "string"}, "target_profile": { "type": "string", "enum": ["MINIMUM", "BASIC_WL", "BASIC", "EN_16931", "EXTENDED", "XRECHNUNG"], }, "target_syntax": {"type": "string", "enum": ["CII", "UBL"], "default": "CII"}, "allow_data_loss": {"type": "boolean", "default": False}, }, "anyOf": [{"required": ["xml_content"]}, {"required": ["xml_base64"]}], }, ) - mcp_einvoicing_de/server.py:15-43 (registration)Import and registration of TOOL_INVOICE_CONVERT (in _ALL_TOOLS at line 31) and handle_invoice_convert (in _TOOL_HANDLERS at line 40) in the MCP server.
from mcp_einvoicing_de import __version__ from mcp_einvoicing_de.tools.invoice_convert import TOOL_INVOICE_CONVERT, handle_invoice_convert from mcp_einvoicing_de.tools.invoice_create import TOOL_INVOICE_CREATE, handle_invoice_create from mcp_einvoicing_de.tools.invoice_parse import TOOL_INVOICE_PARSE, handle_invoice_parse from mcp_einvoicing_de.tools.invoice_validate import TOOL_INVOICE_VALIDATE, handle_invoice_validate from mcp_einvoicing_de.tools.peppol_check import TOOL_PEPPOL_CHECK, handle_peppol_check from mcp_einvoicing_de.tools.tax_rules import TOOL_TAX_RULES, handle_tax_rules LOG_LEVEL = os.environ.get("EINVOICING_DE_LOG_LEVEL", "INFO").upper() logging.basicConfig(level=getattr(logging, LOG_LEVEL, logging.INFO)) logger = logging.getLogger(__name__) _ALL_TOOLS: list[types.Tool] = [ TOOL_INVOICE_CREATE, TOOL_INVOICE_VALIDATE, TOOL_INVOICE_PARSE, TOOL_INVOICE_CONVERT, TOOL_PEPPOL_CHECK, TOOL_TAX_RULES, ] _TOOL_HANDLERS: dict[str, Any] = { "invoice_create": handle_invoice_create, "invoice_validate": handle_invoice_validate, "invoice_parse": handle_invoice_parse, "invoice_convert": handle_invoice_convert, "peppol_check": handle_peppol_check, "tax_rules": handle_tax_rules, }