Skip to main content
Glama

@conformo/mcp-server

Let Claude, Cursor or any MCP client make and check European e-invoices: XRechnung, ZUGFeRD / Factur-X PDF, Peppol BIS Billing 3.0, plain CII and UBL.

  • Runs on your machine. No account, no API key, no usage limits. Invoices never leave your computer; no tool makes a network call.

  • Same verdict as the official validator. validate_invoice runs the official KoSIT, CEN and Peppol rules plus the XSDs. Its verdicts match the official KoSIT validator 100% on the official test invoices, and the full comparison is public.

  • Explains what to fix. Every failed rule comes back with the publisher's message, and the common ones also with a plain-language explanation and fix.

  • Free and open source (Apache-2.0). Rule sets are pinned and a daily job tracks KoSIT, CEN and Peppol releases (how).

Quick start for Claude Code: claude mcp add conformo -- npx -y @conformo/mcp-server. Other clients are below. Needs Node.js 20 or newer. MCP Registry name: io.github.arsalmurad/conformo.

Then ask your agent things like:

  • "Make an XRechnung for Stadt Musterstadt, Leitweg-ID 04011000-1234512345-06, 10 hours of consulting at 95 EUR, and check it."

  • "Is this invoice valid? Explain every error and fix it." (paste the XML, or give a ZUGFeRD PDF)

  • "Turn this UBL invoice into a ZUGFeRD PDF."

  • "What does BR-DE-15 mean?"

Every tool is a thin wrapper over @conformo/toolkit. Two transports: stdio (default, for desktop clients) and stateless Streamable HTTP (for a shared deployment).

Tools

Tool

What it does

Read-only

create_invoice

Structured invoice (JSON object) to XML: cii, cii-extended, ubl, xrechnung-cii, xrechnung-ubl, peppol-ubl.

yes

create_invoice_pdf

Same input to a Factur-X / ZUGFeRD PDF/A-3 (en16931, xrechnung, extended). Returns base64, or writes outputPath.

no

validate_invoice

XML text or base64 PDF. Detects syntax and profile, runs XSD and the matching rule sets, reports which ran. Optional country FR or DE.

yes

convert_invoice

XML or PDF in, another syntax out.

yes

parse_invoice

XML or PDF to the invoice JSON model.

yes

get_country_requirements

Mandates, dates, thresholds and sources per country, plus what Conformo itself supports.

yes

explain_validation_rule

A rule id such as BR-CO-15: official wording, plain-language meaning and fix.

yes

All tools declare an outputSchema and return structuredContent plus a text fallback. Money is always integer minor units (EUR 12.34 is 1234). The input schema of create_invoice documents every field with its BT/BG identifier. Input problems come back as an isError result listing every issue (path, BT id, message), never a stack trace.

Related MCP server: Fintom8 E-Invoice MCP Server

Install and configure

The commands below use the published package name. From a checkout, replace npx -y @conformo/mcp-server with npx tsx /absolute/path/to/conformo/packages/mcp-server/src/server.ts.

Claude Desktop

Add to claude_desktop_config.json (Settings, Developer, Edit Config):

{
  "mcpServers": {
    "conformo": {
      "command": "npx",
      "args": ["-y", "@conformo/mcp-server"]
    }
  }
}

On Windows, if npx is not found, use "command": "cmd" with "args": ["/c", "npx", "-y", "@conformo/mcp-server"].

Claude Code

claude mcp add conformo -- npx -y @conformo/mcp-server
# or against a remote deployment
claude mcp add --transport http conformo https://mcp.example.com/mcp

Cursor

.cursor/mcp.json in the project, or ~/.cursor/mcp.json for all projects:

{
  "mcpServers": {
    "conformo": {
      "command": "npx",
      "args": ["-y", "@conformo/mcp-server"]
    }
  }
}

Working directory and outputPath

create_invoice_pdf can write a file instead of returning base64. The path must end in .pdf, stay inside the server's working directory, and not exist yet unless overwrite: true. Set CONFORMO_MCP_ALLOW_ANY_PATH=1 to lift the directory limit.

HTTP mode

conformo-mcp --http --port 8787 --host 127.0.0.1 --max-body-bytes 8388608

Flag

Env

Default

--port

CONFORMO_MCP_PORT

8787 (0 picks a free port; the URL is printed on stderr)

--host

CONFORMO_MCP_HOST

127.0.0.1

--max-body-bytes

CONFORMO_MCP_MAX_BODY_BYTES

8388608 (8 MiB); larger bodies get 413

Endpoints: POST /mcp (JSON-RPC, JSON responses), GET /healthz (liveness), GET/DELETE /mcp answer 405. The server is stateless: a fresh server and transport per request, no session ids, no data kept between calls. It has no authentication and no TLS.

Remote deployment

Do not expose the port directly. Run it on a private interface and put a reverse proxy with TLS and authentication in front (a bearer token check, mTLS, or your identity-aware proxy). Because it is stateless you can run any number of replicas behind a load balancer with no sticky sessions. Bind to 0.0.0.0 only inside a container or private network.

Dockerfile:

FROM node:22-slim
WORKDIR /app
RUN npm install -g @conformo/mcp-server
ENV CONFORMO_MCP_HOST=0.0.0.0 CONFORMO_MCP_PORT=8787
EXPOSE 8787
USER node
HEALTHCHECK CMD node -e "fetch('http://127.0.0.1:8787/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
CMD ["conformo-mcp", "--http"]

Caddy example (token auth and TLS in front):

mcp.example.com {
  @authed header Authorization "Bearer {env.MCP_TOKEN}"
  handle @authed {
    reverse_proxy 127.0.0.1:8787
  }
  respond "unauthorized" 401
}

Note that invoices contain personal and commercial data: whoever can reach the endpoint can send invoices through it, and you carry the usual obligations for the traffic your proxy logs.

What it does not do

  • It does not transmit invoices: no Peppol access point, no French PA/PDP, no KSeF, no SdI. It produces and checks documents only.

  • It does not support FatturaPA or Facturae (no serializer, reader or validator). KSeF FA(3) is limited to writing domestic PLN invoices and checking them against the Ministry of Finance XSD; it cannot read them.

  • A valid: true means the rule sets listed in ruleSets and the XSD passed. It is not a statement that any tax authority, buyer or network will accept the invoice.

  • It does not compute anything you did not supply beyond totals and the VAT breakdown; exchange rates (BT-111) and exemption reasons are your input.

  • get_country_requirements reports a sourced dataset; entries marked unverified are not confirmed from an official source. It is not legal advice.

  • No authentication, authorisation, rate limiting or persistence in the server itself.

  • Local PDF writing is limited to the working directory unless you opt out; there is no network access from any tool.

Design decisions are recorded in DECISIONS.txt.

Available Tools

7 tools
convert_invoiceConvert an e-invoice between syntaxesA
Read-onlyIdempotent

Rewrites an existing e-invoice in another syntax, for example CII to UBL, or plain EN 16931 to XRechnung or Peppol BIS. Use it when you already hold an invoice document. To build one from data use create_invoice; to get a PDF from XML use parse_invoice, then create_invoice_pdf. Accepts XML or a Factur-X / ZUGFeRD PDF. Nothing is invented: a target such as XRechnung may need data the source lacks, so read warnings and run validate_invoice on the result. A document it cannot read comes back as an error result with the reason. Runs locally; nothing is sent anywhere.

NameRequiredDescriptionDefault
toYesOutput syntax. "cii" = UN/CEFACT CII, EN 16931 (Factur-X / ZUGFeRD EN 16931 profile, a.k.a. COMFORT); "cii-extended" = UN/CEFACT CII declared as Factur-X / ZUGFeRD EXTENDED (EN 16931 content only; no EXTENDED-only fields); "ubl" = UBL 2.1 Invoice or CreditNote, EN 16931; "xrechnung-cii" = XRechnung 3.x in CII syntax (German CIUS); "xrechnung-ubl" = XRechnung 3.x in UBL syntax (German CIUS); "peppol-ubl" = Peppol BIS Billing 3.0 (UBL); "ksef-fa3" = Polish KSeF FA(3), PLN domestic invoices only; written and schema-checked, never submitted.
xmlNoThe invoice as XML text (CII, UBL Invoice/CreditNote, XRechnung, Peppol BIS). Provide this OR pdfBase64.
pdfBase64NoA Factur-X / ZUGFeRD PDF/A-3 as base64; the embedded XML is used. Provide this OR xml.

Output Schema

NameRequiredDescription
xmlYesThe invoice in the target syntax.
fromYesSyntax of the source: cii, ubl-invoice or ubl-credit-note.
formatYesThe syntax that was written.
warningsYesNon-fatal findings, e.g. data the target requires that the source does not have.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the readOnly/idempotent/non-destructive annotations: it warns that conversion invents nothing, that a target profile like XRechnung may lack required source data and surfaces `warnings`, and that unreadable documents return an error result with a reason. It also discloses local execution ("nothing is sent anywhere"), corroborating openWorldHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what the tool does, then alternatives, then input forms, then behavioral caveats and failure mode — a logical escalation with no filler. Each sentence supplies information the agent would otherwise have to infer.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even though an output schema exists and return values needn't be spelled out, the description covers the parts that matter for a conversion tool: input acceptance, lossy-conversion risk, warning inspection, and error behavior. Nothing an agent needs in order to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the enum and per-parameter descriptions already carry the load, and the description correctly does not repeat them. It still adds useful framing that only one of xml or pdfBase64 is supplied and that Factur-X/ZUGFeRD PDFs are accepted as input, plus concrete example target syntaxes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Rewrites an existing e-invoice in another syntax") and grounds it with concrete conversions (CII to UBL, EN 16931 to XRechnung or Peppol BIS). An agent can immediately tell this apart from create_invoice or parse_invoice without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly scopes usage to when the caller "already hold[s] an invoice document" and routes the other cases: build from data → create_invoice, XML to PDF → parse_invoice then create_invoice_pdf. It also names the follow-up step (validate_invoice on the result) and the accepted input forms.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_invoiceCreate an e-invoice (XML)A
Read-onlyIdempotent

Builds e-invoice XML from structured invoice data: EN 16931 CII or UBL, XRechnung (CII or UBL) or Peppol BIS Billing 3.0, chosen by format. Use it for a new invoice that software will read. For a printable PDF with the XML inside, use create_invoice_pdf; to change the syntax of an invoice you already have, use convert_invoice. Pass invoice as a JSON object, not a string. Every money field ends in "Minor" and is an integer in minor units (EUR 12.34 = 1234); totals and the VAT breakdown are computed, so do not send them. If fields are missing or wrong it returns an error listing every problem (path, BT id, message) and produces nothing; fix them all and call again. It runs locally and does not send the invoice anywhere. It does not run the official rule sets: call validate_invoice on the XML before it goes out.

NameRequiredDescriptionDefault
formatYesOutput syntax. "cii" = UN/CEFACT CII, EN 16931 (Factur-X / ZUGFeRD EN 16931 profile, a.k.a. COMFORT); "cii-extended" = UN/CEFACT CII declared as Factur-X / ZUGFeRD EXTENDED (EN 16931 content only; no EXTENDED-only fields); "ubl" = UBL 2.1 Invoice or CreditNote, EN 16931; "xrechnung-cii" = XRechnung 3.x in CII syntax (German CIUS); "xrechnung-ubl" = XRechnung 3.x in UBL syntax (German CIUS); "peppol-ubl" = Peppol BIS Billing 3.0 (UBL); "ksef-fa3" = Polish KSeF FA(3), PLN domestic invoices only; written and schema-checked, never submitted.
invoiceYesThe invoice. Required: number, issueDate, currency, seller, buyer, lines.

Output Schema

NameRequiredDescription
xmlYesThe e-invoice XML, ready to send or to pass to validate_invoice.
formatYesThe syntax that was written.
warningsYesNon-fatal findings, e.g. a missing XRechnung precondition.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/local, and the description adds substantive behavior beyond them: the tool runs locally and sends nothing, a failure is atomic ("produces nothing") and returns an error enumerating every problem by path, BT id and message. It also discloses a real limitation not in any annotation — the official rule sets are not run, so validate_invoice must be called separately.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Six tight sentences, front-loaded with purpose then routing then input conventions then failure behavior. No filler, though the minor-units and computed-totals guidance partially repeats per-field schema descriptions and could be trimmed to one clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool wrapping a very large nested schema with an output schema available, the description covers the essentials: format choice, input conventions, atomic failure, locality, and the validation handoff. It does not mention format-specific field requirements (XRechnung mandatory seller contact, Peppol/France electronic address), but those are documented in the schema itself.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns an extra point by stating conventions that matter at call time but are easy to miss across a 100-field schema: `invoice` is an object not a JSON string, every money field is an integer in minor units, and totals/VAT breakdown must not be sent because they are computed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ("Builds e-invoice XML from structured invoice data") and enumerates the supported syntaxes (EN 16931 CII/UBL, XRechnung, Peppol BIS 3.0) selected by `format`. It explicitly differentiates itself from create_invoice_pdf and convert_invoice, so the agent can choose without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States the use case ("for a new invoice that software will read") and names three alternatives with the exact condition that selects each: create_invoice_pdf for PDF, convert_invoice for changing syntax, validate_invoice before sending. When-to-use, when-not-to-use, and alternatives are all present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_invoice_pdfCreate a Factur-X / ZUGFeRD PDFA
DestructiveIdempotent

Builds a Factur-X / ZUGFeRD invoice: a PDF/A-3b page a person can read, with the EN 16931 XML embedded for software. Use it when the invoice goes to a person or by e-mail. For XML only, such as an XRechnung uploaded to a German public-sector portal, use create_invoice. Takes the same invoice object as create_invoice, money in integer minor units. language changes only the printed labels; the embedded XML is identical in every language. By default the PDF comes back as base64, which can be large; pass outputPath to write the file instead. Writing stays inside the server's working directory and never replaces an existing file unless overwrite is true. The same input always gives the same bytes, and nothing is sent anywhere. Check the result with validate_invoice (pass pdfBase64).

NameRequiredDescriptionDefault
invoiceYesThe invoice. Required: number, issueDate, currency, seller, buyer, lines.
profileNoFactur-X / ZUGFeRD profile. Default en16931.
languageNoLanguage of the printed labels: en, de or fr. Default en. Presentation only; the XML does not change.
templateNoPage layout. Default classic.
overwriteNoAllow replacing an existing file at outputPath. Default false.
outputPathNoWrite the PDF here instead of returning base64. Relative to the server working directory; must end in .pdf.

Output Schema

NameRequiredDescription
sha256YesSHA-256 of the PDF bytes, hex; equal for equal input.
profileYesThe Factur-X / ZUGFeRD profile written.
warningsYesNon-fatal findings about the invoice data.
pdfBase64NoThe PDF, base64. Absent when outputPath was given.
byteLengthYesSize of the PDF in bytes.
outputPathNoAbsolute path written, when outputPath was given.
xmlFilenameYesName of the embedded XML attachment.
conformanceLevelYesConformance level declared in the PDF metadata, e.g. EN 16931.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds concrete behavior the agent could not otherwise know: writes are confined to the server working directory, an existing file is never replaced unless overwrite is true, output is byte-deterministic, nothing leaves the process, and the default base64 payload can be large enough to warrant outputPath. These are exactly the operational facts a caller needs before invoking a file-writing tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence is front-loaded with purpose and carries a distinct fact: what it builds, when to use it, when not to, input contract, language behavior, output channel, overwrite safety, determinism, and verification. No sentence repeats the schema or the annotations, and nothing is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter tool with a deeply nested invoice schema and an output schema already present, the description covers the decision-relevant surface: artifact choice, input reuse, output channel trade-off, filesystem safety, determinism, and next-step validation. Return-value shape is correctly left to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline would be 3, but the description adds real meaning: it explains that `language` affects only printed labels while the embedded XML is identical, that `outputPath` switches the return channel from base64 to a file, that writes are sandboxed to the working directory, and that the `invoice` object is shared with create_invoice and uses integer minor units. Only per-parameter details like profile/template semantics are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names the exact artifact (a Factur-X / ZUGFeRD PDF/A-3b page with EN 16931 XML embedded), which is far more specific than the name alone, and the second sentence distinguishes it from the sibling create_invoice (XML only). An agent can tell instantly which of the two produces a human-readable document.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the positive trigger ("when the invoice goes to a person or by e-mail") and the negative one ("For XML only, such as an XRechnung uploaded to a German public-sector portal, use create_invoice"), naming the alternative explicitly. It also routes post-generation verification to validate_invoice with the pdfBase64 argument.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_validation_ruleExplain a validation ruleA
Read-onlyIdempotent

Explains one validation rule id, such as BR-CO-15, BR-DE-15, PEPPOL-EN16931-R003 or BR-FR-05: the publisher's official wording from the compiled rule sets and, where available, a plain-language summary, the reason for the rule and how to fix it. Use it after validate_invoice reports a rule you need to explain or fix, or when a user asks what a rule means. It does not check an invoice; call validate_invoice for that. An unknown id is not an error: the result has found false and an empty official list; say so and do not guess. Reads the bundled rule sets; no network.

NameRequiredDescriptionDefault
ruleIdYesThe rule id, e.g. BR-CO-15.

Output Schema

NameRequiredDescription
foundYesFalse when no compiled rule set knows this id.
ruleIdYesThe rule id as looked up.
officialYesOfficial wording, one entry per rule set that defines the id.
plainLanguageNoPlain-language explanation, when one exists for this rule.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, closed-world and non-destructive, so the safety profile is covered. The description still adds real behavioral context beyond them: unknown ids are not errors but yield `found` false with an empty `official` list, and the tool reads bundled rule sets with no network access. That said, it does not describe result sizing or how large the official wording list can get, so it is useful but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense paragraph, front-loaded with the verb/resource and the id formats, then usage, then the negative case, then data sourcing. Every clause earns its place; the 'does not check an invoice' sentence is a deliberate disambiguation rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, read-only lookup with an output schema, the description covers purpose, routing, edge-case behavior and data provenance. Return values are backed by the output schema, and the description goes further by naming the `found`/`official` fields for the miss case so an agent knows what to report to the user.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single `ruleId` parameter is already documented with its own example, so the schema carries the parameter burden. The description reinforces the id format with several additional naming conventions (PEPPOL-EN16931-R003, BR-FR-05), which helps an agent recognize valid ids but adds no new constraints. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Explains one validation rule id') and immediately grounds it with concrete id examples (BR-CO-15, BR-DE-15, PEPPOL-EN16931-R003, BR-FR-05), making clear it is a lookup/explanation tool, not a validator. It explicitly distinguishes itself from validate_invoice, so an agent can route correctly without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit triggering conditions ('after validate_invoice reports a rule you need to explain or fix, or when a user asks what a rule means') and an explicit exclusion ('It does not check an invoice; call validate_invoice for that'). The alternative sibling and the condition that selects it are named outright, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_country_requirementsE-invoicing requirements for a countryA
Read-onlyIdempotent

Looks up the e-invoicing rules for one country in a sourced dataset: B2G and B2B mandates for issuing and receiving, start dates, turnover thresholds, required formats and official sources. Use it before create_invoice to decide which format a buyer in that country needs, or to answer when a mandate applies. It says nothing about a specific invoice; use validate_invoice to check one. Covers BE, DE, ES, FR, IT, NL, PL. conformoSupport says per format whether this server can create, read and validate it. Entries marked unverified are not confirmed from an official source; say so. Information, not legal advice. Reads a bundled dataset; no network.

NameRequiredDescriptionDefault
countryYesISO 3166-1 alpha-2 country code, e.g. DE, FR.

Output Schema

NameRequiredDescription
countryYesISO 3166-1 alpha-2 code of the country returned.
conformoSupportYesPer required format, what this server can do with it.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, idempotent and the closed-world nature, but the description adds real context beyond them: a data-quality caveat that 'unverified' entries are not confirmed from an official source and must be disclosed, plus the meaning of the `conformoSupport` field. Minor overlap exists in restating 'no network', which duplicates openWorldHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then alternatives, then caveats; nearly every sentence carries distinct information. Slight redundancy in 'Reads a bundled dataset; no network' echoing the openWorldHint annotation, but overall tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, yet the description still clarifies the key embedded field (`conformoSupport`) and the trust caveat for unverified entries. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; however the description adds the supported country domain (BE, DE, ES, FR, IT, NL, PL) that the schema does not encode via enum. That materially constrains valid inputs beyond the ISO-code description in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a precise verb and resource ('Looks up the e-invoicing rules for one country in a sourced dataset') and enumerates the returned content (B2G/B2B mandates, start dates, thresholds, formats, sources). It is immediately distinguishable from siblings like validate_invoice and create_invoice.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it ('before create_invoice to decide which format a buyer needs') and draws a clear exclusion boundary ('It says nothing about a specific invoice; use validate_invoice to check one'). This is the when/when-not/alternative pattern done fully.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

parse_invoiceParse an e-invoice into JSONA
Read-onlyIdempotent

Reads an e-invoice (CII, UBL, XRechnung or Peppol XML, or a Factur-X / ZUGFeRD PDF) into the structured invoice object that create_invoice accepts, with money in integer minor units. Use it to answer questions about a received invoice, to edit one, or to re-issue it with create_invoice. It does not check any rules, so use validate_invoice for that, and convert_invoice to change syntax directly. For a PDF, visibleTotals shows whether the totals printed on the page match the embedded XML, which exposes a tampered or mismatched PDF. A document it cannot read comes back as an error result with the reason. Runs locally.

NameRequiredDescriptionDefault
xmlNoThe invoice as XML text (CII, UBL Invoice/CreditNote, XRechnung, Peppol BIS). Provide this OR pdfBase64.
pdfBase64NoA Factur-X / ZUGFeRD PDF/A-3 as base64; the embedded XML is used. Provide this OR xml.

Output Schema

NameRequiredDescription
formatYesSyntax of the source document.
originYesWhether the input was XML or a PDF.
invoiceYesThe Invoice object, in the shape of the create_invoice input schema.
visibleTotalsNoPDF only: comparison of the printed totals with the embedded XML.
embeddedFilenameNoPDF only: name of the embedded XML that was read.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/idempotent/non-destructive, and the description adds behavior beyond them: output is the same object create_invoice accepts with money in integer minor units, unreadable documents return an error result with a reason, and it runs locally. The visibleTotals disclosure for PDFs (page totals vs embedded XML, exposing tampering) is precisely the kind of non-obvious behavioral detail an agent cannot get from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and accepted formats are front-loaded in the first clause, then usage, sibling routing, PDF caveat, and error behavior follow in descending priority. Every sentence carries distinct information; the 'exposes a tampered or mismatched PDF' clause is a short payoff, not padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read tool with a full output schema and complete annotations, the description supplies everything else an agent needs: accepted syntaxes, output contract, failure mode, and the three sibling-routing decisions. Nothing material is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters already document the 'provide this OR pdfBase64' exclusivity, so the baseline is 3. The description reinforces that a PDF path exists and explains what the embedded XML yields, but it adds no format or precedence detail beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource (reads an e-invoice into a structured invoice object) and enumerates the exact accepted syntaxes (CII, UBL, XRechnung, Peppol XML, Factur-X/ZUGFeRD PDF). It goes further by tying the output to create_invoice's input shape with integer minor units, which lets an agent distinguish it from validate_invoice and convert_invoice without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit use cases (answer questions about a received invoice, edit one, re-issue it with create_invoice) and explicit exclusions with named alternatives: no rule checking, so use validate_invoice; to change syntax directly, use convert_invoice. This is the full when/when-not/alternative triad.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_invoiceValidate an e-invoiceA
Read-onlyIdempotent

Checks an e-invoice against the official rule sets on this machine: the XSD, the EN 16931 Schematron from CEN, and the KoSIT XRechnung or Peppol BIS rules when the document declares them. Use it before sending an invoice you created and when you receive one. To read the invoice's data use parse_invoice; to explain one failed rule in depth use explain_validation_rule. Accepts XML or a Factur-X / ZUGFeRD PDF, whose embedded XML is checked; syntax and profile are detected from the document. A valid result means the listed ruleSets passed, not that a tax authority or buyer will accept the invoice, so report which rule sets ran and never claim more. Each failure carries the publisher's message and, for common rules, a plain-language fix. Input that is not an invoice comes back as an error result, not as invalid. The check runs offline; nothing is uploaded.

NameRequiredDescriptionDefault
xmlNoThe invoice as XML text (CII, UBL Invoice/CreditNote, XRechnung, Peppol BIS). Provide this OR pdfBase64.
xsdNoRun XSD validation too. Default true.
countryNoAdd a country layer: "FR" runs the French CTC rules (CII only); "DE" reports whether the profile is acceptable for German B2B (MINIMUM and BASIC WL are not).
profileNoForce the rule set instead of reading it from BT-24.
pdfBase64NoA Factur-X / ZUGFeRD PDF/A-3 as base64; the embedded XML is used. Provide this OR xml.

Output Schema

NameRequiredDescription
xsdYesXML Schema check.
validYesTrue only when no error-level rule failed, the XSD did not fail, and no error-level notice was raised.
originYesWhether the input was XML or a PDF.
noticesYesFindings about the document that are not Schematron rules, e.g. an unrecognised profile, or (with country DE) a profile not acceptable for German B2B. An error-level notice makes valid false.
detectedYesWhat the document declares about itself.
failuresYesError-level rules that failed; any entry makes valid false.
ruleSetsYesExactly the rule sets that ran. Report these; do not claim checks that are not listed.
advisoriesYesWarning or info rules that fired; they do not make the invoice invalid.
firedCountYesSchematron rules that fired across all rule sets.
embeddedFilenameNoPDF only: name of the embedded XML that was checked.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive and closed-world, and the description still adds substantial context: rule-set detection from the document, that `valid` only means the listed `ruleSets` passed and implies no tax-authority acceptance, that non-invoice input yields an error rather than an invalid verdict, and that the check is offline with no upload. This is exactly the kind of scope-limiting detail annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and each sentence carries information — the valid/ruleSets caveat and the error-vs-invalid distinction are high-value. It is somewhat dense and the accepted-input sentence sits mid-paragraph rather than next to the purpose, but nothing is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, yet the description still pre-empts the main misinterpretation risk (over-claiming acceptance) and notes that failures carry the publisher's message plus plain-language fixes. Nothing an agent needs in order to call it and report results correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real meaning: it clarifies that syntax and profile are auto-detected unless overridden, and that for a Factur-X/ZUGFeRD PDF the embedded XML is what gets checked. The remaining parameters (xsd, country) are left entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — checking an e-invoice against named rule sets (XSD, EN 16931 Schematron, KoSIT XRechnung/Peppol BIS) — and explicitly distinguishes itself from parse_invoice and explain_validation_rule. An agent can identify the tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance (before sending an invoice you created, and when receiving one) and names both alternatives with the condition that selects them. No inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool update
    • Changedvalidate_invoice4 fields changed
      • addedOutput schema / properties / failures / items / properties / element
        Added value: +{
        +  "description": "The offending element without namespaces, e.g. LineTotalAmount.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / failures / items / properties / line
        Added value: +{
        +  "description": "1-based invoice line number when the node is inside an invoice line.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / failures / items / properties / path
        Added value: +{
        +  "description": "A short readable path, e.g. \"line 1 > NetPriceProductTradePrice > ChargeAmount\". xpath is the exact location.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / failures / items / properties / plainLanguage / description
        Previous value: -"Plain-language explanation and fix, present for common rules."New value: +"Plain-language explanation and fix, present for common rules and for the syntax rules (CII-DT, CII-SR, UBL-CR, UBL-DT, UBL-SR)."
  2. 7 tool updates
    • Changedconvert_invoice3 fields changed
      • addedOutput schema / properties / format / description
        Added value: +"The syntax that was written."
      • addedOutput schema / properties / warnings / description
        Added value: +"Non-fatal findings, e.g. data the target requires that the source does not have."
      • addedOutput schema / properties / xml / description
        Added value: +"The invoice in the target syntax."
    • Changedcreate_invoice2 fields changed
      • addedOutput schema / properties / format / description
        Added value: +"The syntax that was written."
      • addedOutput schema / properties / xml / description
        Added value: +"The e-invoice XML, ready to send or to pass to validate_invoice."
    • Changedcreate_invoice_pdf5 fields changed
      • addedOutput schema / properties / byteLength / description
        Added value: +"Size of the PDF in bytes."
      • addedOutput schema / properties / conformanceLevel / description
        Added value: +"Conformance level declared in the PDF metadata, e.g. EN 16931."
      • addedOutput schema / properties / profile / description
        Added value: +"The Factur-X / ZUGFeRD profile written."
      • addedOutput schema / properties / sha256 / description
        Added value: +"SHA-256 of the PDF bytes, hex; equal for equal input."
      • addedOutput schema / properties / warnings / description
        Added value: +"Non-fatal findings about the invoice data."
    • Changedexplain_validation_rule9 fields changed
      • addedOutput schema / properties / found / description
        Added value: +"False when no compiled rule set knows this id."
      • addedOutput schema / properties / official / description
        Added value: +"Official wording, one entry per rule set that defines the id."
      • addedOutput schema / properties / official / items / properties / ruleSet / description
        Added value: +"Rule set containing the rule."
      • addedOutput schema / properties / official / items / properties / text / description
        Added value: +"The publisher's wording of the rule."
      • addedOutput schema / properties / plainLanguage / description
        Added value: +"Plain-language explanation, when one exists for this rule."
      • addedOutput schema / properties / plainLanguage / properties / fix / description
        Added value: +"How to change the invoice so the rule passes."
      • addedOutput schema / properties / plainLanguage / properties / summary / description
        Added value: +"What the rule requires, in plain language."
      • addedOutput schema / properties / plainLanguage / properties / why / description
        Added value: +"Why the rule exists or why it typically fires."
      • addedOutput schema / properties / ruleId / description
        Added value: +"The rule id as looked up."
    • Changedget_country_requirements6 fields changed
      • addedOutput schema / properties / conformoSupport / additionalProperties / properties / generate / description
        Added value: +"This server can create the format."
      • addedOutput schema / properties / conformoSupport / additionalProperties / properties / note / description
        Added value: +"Limits that apply."
      • addedOutput schema / properties / conformoSupport / additionalProperties / properties / read / description
        Added value: +"This server can read the format."
      • addedOutput schema / properties / conformoSupport / additionalProperties / properties / validate / description
        Added value: +"This server can validate the format."
      • addedOutput schema / properties / conformoSupport / description
        Added value: +"Per required format, what this server can do with it."
      • addedOutput schema / properties / country / description
        Added value: +"ISO 3166-1 alpha-2 code of the country returned."
    • Changedparse_invoice3 fields changed
      • addedOutput schema / properties / embeddedFilename / description
        Added value: +"PDF only: name of the embedded XML that was read."
      • addedOutput schema / properties / format / description
        Added value: +"Syntax of the source document."
      • addedOutput schema / properties / origin / description
        Added value: +"Whether the input was XML or a PDF."
    • Changedvalidate_invoice36 fields changed
      • changedInput schema / properties / country / description
        Previous value: -"Add a country layer on top of EN 16931."New value: +"Add a country layer: \"FR\" runs the French CTC rules (CII only); \"DE\" reports whether the profile is acceptable for German B2B (MINIMUM and BASIC WL are not)."
      • addedOutput schema / properties / advisories / description
        Added value: +"Warning or info rules that fired; they do not make the invoice invalid."
      • addedOutput schema / properties / detected / description
        Added value: +"What the document declares about itself."
      • addedOutput schema / properties / detected / properties / businessProcess / description
        Added value: +"BT-23 business process, when present."
      • addedOutput schema / properties / detected / properties / customizationId / description
        Added value: +"The BT-24 specification identifier as written in the document."
      • addedOutput schema / properties / detected / properties / profile / description
        Added value: +"Profile read from BT-24: en16931, xrechnung, peppol, extended, minimum, basicwl or unknown."
      • addedOutput schema / properties / detected / properties / syntax / description
        Added value: +"cii, ubl-invoice or ubl-credit-note."
      • addedOutput schema / properties / detected / properties / variant / description
        Added value: +"XRechnung only: standard, extension or cvd."
      • addedOutput schema / properties / embeddedFilename / description
        Added value: +"PDF only: name of the embedded XML that was checked."
      • addedOutput schema / properties / failures / description
        Added value: +"Error-level rules that failed; any entry makes valid false."
      • addedOutput schema / properties / failures / items / properties / fields / description
        Added value: +"BT and BG ids named in the official message, in order."
      • addedOutput schema / properties / failures / items / properties / message / description
        Added value: +"The publisher's own message for this rule."
      • addedOutput schema / properties / failures / items / properties / plainLanguage / description
        Added value: +"Plain-language explanation and fix, present for common rules."
      • addedOutput schema / properties / failures / items / properties / plainLanguage / properties / fix / description
        Added value: +"How to change the invoice so the rule passes."
      • addedOutput schema / properties / failures / items / properties / plainLanguage / properties / summary / description
        Added value: +"What the rule requires, in plain language."
      • addedOutput schema / properties / failures / items / properties / plainLanguage / properties / why / description
        Added value: +"Why the rule exists or why it typically fires."
      • addedOutput schema / properties / failures / items / properties / ruleId / description
        Added value: +"Rule id from the publisher, e.g. BR-CO-15 or BR-DE-15."
      • addedOutput schema / properties / failures / items / properties / ruleSet / description
        Added value: +"Id of the rule set the rule belongs to (see ruleSets)."
      • addedOutput schema / properties / failures / items / properties / severity / description
        Added value: +"error and fatal fail the invoice; warning and info do not. Effective level after the publisher's own re-levelling."
      • addedOutput schema / properties / failures / items / properties / xpath / description
        Added value: +"Where in the XML the rule fired."
      • addedOutput schema / properties / notices / description
        Added value: +"Findings about the document that are not Schematron rules, e.g. an unrecognised profile, or (with country DE) a profile not acceptable for German B2B. An error-level notice makes valid false."
      • addedOutput schema / properties / origin / description
        Added value: +"Whether the input was XML or a PDF."
      • addedOutput schema / properties / ruleSets / description
        Added value: +"Exactly the rule sets that ran. Report these; do not claim checks that are not listed."
      • addedOutput schema / properties / ruleSets / items / properties / advisory / description
        Added value: +"Warning or info rules that fired without failing the invoice."
      • addedOutput schema / properties / ruleSets / items / properties / failed / description
        Added value: +"Error-level rules that failed."
      • addedOutput schema / properties / ruleSets / items / properties / fired / description
        Added value: +"Rules of this set that applied to the document."
      • addedOutput schema / properties / ruleSets / items / properties / id / description
        Added value: +"Rule set id, e.g. en16931-cii or xrechnung-cii."
      • addedOutput schema / properties / ruleSets / items / properties / label / description
        Added value: +"Human-readable name."
      • addedOutput schema / properties / ruleSets / items / properties / source / description
        Added value: +"Publisher and version of the official artefact that ran."
      • addedOutput schema / properties / valid / description
        Added value: +"True only when no error-level rule failed, the XSD did not fail, and no error-level notice was raised."
      • addedOutput schema / properties / xsd / description
        Added value: +"XML Schema check."
      • addedOutput schema / properties / xsd / properties / errors / description
        Added value: +"XSD errors, empty when valid."
      • addedOutput schema / properties / xsd / properties / ran / description
        Added value: +"Whether XSD validation ran."
      • addedOutput schema / properties / xsd / properties / schema / description
        Added value: +"The XSD used."
      • addedOutput schema / properties / xsd / properties / skippedReason / description
        Added value: +"Why XSD did not run, when it did not."
      • addedOutput schema / properties / xsd / properties / valid / description
        Added value: +"XSD verdict, when it ran."
  3. 7 tool updatesv0.2.1
    • First observedconvert_invoice
    • First observedcreate_invoice
    • First observedcreate_invoice_pdf
    • First observedexplain_validation_rule
    • First observedget_country_requirements
    • First observedparse_invoice
    • First observedvalidate_invoice

TDQS

A4.6/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a narrowly distinct purpose, and the descriptions explicitly cross-reference siblings to steer selection (create_invoice vs create_invoice_pdf vs convert_invoice; validate_invoice vs explain_validation_rule vs parse_invoice; get_country_requirements is clearly advisory only). There is no pair an agent could plausibly confuse.

Naming Consistency5/5

All seven names follow a consistent snake_case verb_noun pattern (create_, validate_, convert_, parse_, explain_, get_). The single compound suffix create_invoice_pdf follows the same convention and reads naturally alongside create_invoice.

Tool Count5/5

Seven tools is tightly scoped to the e-invoicing lifecycle, with each tool earning its place: two creation targets (XML, PDF), parsing, conversion, validation, rule explanation, and country requirements. Nothing looks redundant or padded.

Completeness4/5

The surface covers the full document lifecycle: build (XML/PDF), read (parse), transform (convert), check (validate), explain failures, and decide format per country. Minor gaps remain, such as no tool to enumerate supported rule sets/profiles or to bulk-validate, but parse → edit → create covers the update case.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    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
    5
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Validates EU electronic invoices (Peppol, XRechnung, FatturaPA, etc.) and explains validation error codes, enabling AI coding agents to check invoice validity and get fixes before rejection.
    3
    39 npm
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to create and manage e-invoices through natural language, supporting EU compliance formats like ZUGFeRD and XRechnung, as well as US plain PDF invoices.
    7
    -