Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.8.6] - 2026-09-07
Changed
- regulatory-update: Peppol BIS 3.0 (PEF/B2G) spec pin 3.0.20 → 3.0.21, closes
regulatory-updateissue #11. Same upstream release also flagged formcp-einvoicing-be: released 2026-05-20, mandatory from 2026-08-17. New optional Profile 02 “Billing with Response”, UBL/CII 1.3.16,PEPPOL-COMMON-R052/R053raised to error, new Dutch-identifier rules — all inside the Peppol-specific Schematron overlay, which this package has never run (nopeppol/business-rule validation exists here at all;peppol/generator.py,parser.py,serializer.pyonly delegate to core’s UBL serializer/parser). Documentation-only pin refresh (context-library/countries/pl.mdat the workspace root); no code change.
[0.8.4] - 2026-08-31
Fixed
- PL-ERR-1:
KSeFClient._request’s KSeF-structured-error re-raise (_raise_ksef_error) was unreachable dead code — it only ran whenexc.response_bodywas truthy, butmcp-einvoicing-core’sPlatformErrornever set that attribute, so every KSeF error surfaced as core’s genericHTTP error <code>message instead of KSeF’s own{"exceptionCode": ..., "message": ...}body. Fixed bymcp-einvoicing-corev1.28.0, which now threads the raw response body throughPlatformError.response_body; thehasattrguard is removed since the attribute is now always present. - PL-TZ-1:
_to_iso_datetimepassed a naive (offset-less) full datetime string straight through tosearch_documents’sdateRangefilter. Such a value is assumed UTC and now gets+00:00appended; a value already carrying aZsuffix or an explicit offset is unaffected.
Added
KSeFClient._requestnow logs the KSeF API v2.6.0X-System-Warningresponse header (additive, non-fatal) atWARNINGlevel when present on an otherwise-successful response. Does not affect the return value.
Raises the core lower-bound pin to >=1.28.0 (was >=1.27.0).
[0.8.3] - 2026-08-31
Fixed
- PL-DISC-1: the FA(2)/FA(3) XML generators inserted seller/buyer/line-item
and note field values verbatim through
xml_escape(), which only neutralizes the 5 XML metacharacters. KSeF API v2.4.0 (PRD-live since 2026-07-16) rejects an otherwise schema-valid document containing a W3C XML 1.0 Appendix C “discouraged” code point (C1 controls + DEL, certain noncharacters) — a class of rejection the local XSD validator does not catch.generator.pynow routes every text field through a new_escape()wrapper that appliesmcp_einvoicing_core.xml_utils.sanitize_xml_text()(core v1.27.0) before escaping, rejecting generation withDocumentGenerationErrorrather than silently mutating a legally-binding invoice field. Addedtests/test_generator.py::TestDiscouragedCharacterSanitization. - Lower-bound pin on
mcp-einvoicing-coreraised to>=1.27.0(was>=1.20.0) forsanitize_xml_text/DiscouragedCharacterError.
[0.8.2] - 2026-08-24
Fixed
FA2Parser.parse()looked for a<FaWiersze>wrapper around<FaWiersz>rows that does not exist in the FA(2) schema, solineswas always empty for any real FA(2) XML, including this package’s own generator output. Fixed to read<FaWiersz>as a direct child of<Fa>.due_datewas reading<P_6>(date of supply/delivery/service completion), not the payment due date, which lives in<Platnosc>/<TerminPlatnosci>/<Termin>(same schema fact already applied toFA2Generatorin the v0.8.1PL-PAY-1fix).<P_6>is now parsed separately undersupply_date.- Added
tests/test_parser.py— no test file previously existed forFA2Parser, which is how both bugs went unnoticed despiteparse_fa2_invoicebeing a live registered MCP tool.
[0.8.1] - 2026-08-24
Fixed
- PL-PAY-1: FA(2)
<Platnosc>(payment) block was structurally invalid._payment_blockemitted a non-existent invoice-level<P_6>element fordue_dateand an unwrapped<RachunekBankowy>spliced in before<RodzajFaktury>.<P_6>exists in the FA(2) schema but means “date of supply/service completion”, not “payment due date” — it was also positioned wrong even on that reading.due_dateand IBAN now emit inside a<Platnosc>block (TerminPlatnosci,FormaPlatnosci,RachunekBankowy), positioned as a sibling of<FaWiersz>after the invoice lines, mirroring_fa3_platnosc_block’s already-correct FA(3) shape. Not caught by v0.5.0’s XSD-conformance tests becausesample_invoicehad nodue_date/payment_means; addedtests/test_fa2_xsd_conformance.py(payment-bearing FA(2) fixture, generate→XSD-validate) plus a structural unit test intests/test_generator.py.
[0.8.0] - 2026-08-24
Changed
peppol_sendnow emits a realwsse:Securitymessage signature.mcp-einvoicing-corev1.20.0 fixed the AS4 transport client’s_apply_message_signature, which previously computed a signature and discarded it, sending unsigned outbound messages. This is an API-compatible, wire-level behavior change — no code in this package changed to pick it up, but every outbound message sent through this package’speppol_sendis now actually signed. Not yet validated against a live sandbox Peppol AP; treat as unverified at the transport level until that validation runs.- Lower-bound pin on
mcp-einvoicing-coreraised to>=1.20.0(was>=1.19.0).
Added
- New
xslt2extra:mcp-einvoicing-core[xslt2]>=1.20.0. This package had no[xslt2]extra before — it is required by the new EUSR/TSR reporting and MLS tools below.saxonchealso added to thedevextra so reporting/MLS tests run. - Mounted three new opt-in core plugins in
server.py, alongside the existing Peppol tool plugin:register_peppol_reporting_tools(mcp_einvoicing_core.peppol.reporting_tools) —validate_eusr_report,validate_tsr_report(End User / Transaction Statistics Reports). Requires the[xslt2]extra.register_peppol_mls_tools(mcp_einvoicing_core.peppol.mls_tools) —validate_mls_message,build_mls_message(Message Level Status). Requires the[xslt2]extra.register_en16931_codelist_tools(mcp_einvoicing_core.en16931_codelist_tools) — 13list_*/check_*pairs plusget_en16931_codelist_versionfor the EN 16931 semantic code lists. RequiresEINVOICING_EN16931_CODELIST_DIRto be set to a local copy of the CEF Digital code lists (not bundled).peppol_directory_search(public Peppol Directory search) arrives automatically via the existingregister_peppol_toolsmount — noserver.pychange needed for this one.
- All new tools are mounted unconditionally; they raise a clear error at call time (not at registration) when their extra or data directory is missing, matching the existing eDEC codelist tool pattern.
[0.7.0] - 2026-08-22
Added
- Initial changelog. Prior release history is recorded in the Git tags and GitHub Releases for this repository.