npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@attestwire/mcp

v1.1.2

Published

stdio bridge to the Attestwire MCP server — nine EN 16931 e-invoicing compliance tools: validate invoice data, or a UBL 2.1 / UN-CEFACT CII invoice file, against XRechnung and Peppol BIS 3 rules, and emit UBL or CII XML. XML only: it does not read or writ

Readme

@attestwire/mcp

European e-invoicing compliance as MCP tools — EN 16931, XRechnung, Peppol BIS 3.0 and Factur-X. Ask what a rule means, validate a real invoice, emit invoice XML, check whether VIES is up, look up a French company against the 2026-2027 mandate.

Five of the nine tools need no API key at all. Connect with no credential and they work immediately — start there, add a key later.

npx -y @attestwire/mcp

At a glance

| | | |---|---| | Tools | 9 — 5 keyless, 3 keyed and metered, 1 keyed and free | | Hosted at | https://api.attestwire.com/mcp — streamable HTTP, stateless, no session id | | This package | npx -y @attestwire/mcp — a stdio bridge to that endpoint, for clients that cannot speak remote HTTP | | Deterministic | The compliance tools are a rule engine, not a model. The same document against the same ruleset returns the same verdicts, in the same order, every time — no sampling, no temperature, nothing generated. The ruleset is pinned per engine release; GET https://api.attestwire.com/v1/versions names the one that is live. | | Rules | EN 16931 plus the national CIUS: XRechnung (UBL and CII), Peppol BIS 3.0. 270 rule ids explained in plain English — most, not all, of what the validator checks. | | Reads / writes | UBL 2.1 Invoice, UBL 2.1 CreditNote, UN/CEFACT CII CrossIndustryInvoice, in both directions | | Auth | Optional Authorization: Bearer aw_live_... — a bearer API key, not OAuth | | Free tier | 100 documents/month, no card. issue_api_key mints a key from inside the session — but minting does not authenticate the connection it was minted on: save it, configure it, reconnect (§3). | | Runtime | Zero dependencies, Node ≥ 20, MIT |

The disclaimer, up front, because it is the thing people get wrong: this is a pre-flight, not a clearing house. It handles XML and never PDF — a Factur-X or ZUGFeRD file is CII XML inside a PDF/A-3 container, and this server neither opens that container nor builds one. And a document that passes here can still be rejected by KoSIT or by a receiving platform: rules that constrain the XML itself do not run on a file this server read. Nothing here is legal or tax advice. The four limits are spelled out in full below.

Quickstart

1. Connect

If your client speaks streamable HTTP — Claude Code, Claude Desktop custom connectors, Cursor — point it at the hosted endpoint and skip this package entirely:

claude mcp add --transport http attestwire https://api.attestwire.com/mcp

If your client can only spawn a local process, this package is a stdio bridge to that same endpoint. Paste into claude_desktop_config.json, .cursor/mcp.json, or whatever your client calls its MCP config:

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

No env block, no key, nothing to sign up for. See most people do not need this package for which of the two to pick.

2. Make a call, with no credential

Ask the agent, in these words or your own:

Use the attestwire MCP server: explain rule BR-DE-15.

explain_rule is keyless, so this answers on a fresh connection — the rule's requirement, the business term it constrains, a fix and an example. Four other tools work the same way with no key: check_vies_status, check_french_readiness, list_approved_platforms and issue_api_key.

That is the whole first run. Everything below is either the key (§3), the full tool list, or the limits.

3. Add a key — two stages, and the second one is not optional

Authentication is supplied when the client connects: this bridge reads ATTESTWIRE_API_KEY once, at process start, and sends it as an Authorization: Bearer header; a client on the remote HTTP transport sends the header from its own config. Minting a key does not authenticate the connection it was minted on — nothing a tool returns changes a live session's credential, and there is no automatic reauthentication to wait for.

So it is two stages, not one call:

Stage one — get a key.

  1. Mint it. Ask the agent to call issue_api_key with your email address, or fill in the browser form at attestwire.com/#keyform — same endpoint, same instant key. It is free, there is no signup flow and no card.
  2. Save it. The key is shown once and cannot be recovered — only its SHA-256 hash is stored. Put it in a password manager or a secret store, not in the chat you are typing into. The browser form is the better route when you would rather a one-time secret never entered a transcript at all.

Stage two — make the connection carry it.

  1. Configure it. ATTESTWIRE_API_KEY in the env block for this stdio bridge:

    {
      "mcpServers": {
        "attestwire": {
          "command": "npx",
          "args": ["-y", "@attestwire/mcp"],
          "env": { "ATTESTWIRE_API_KEY": "aw_live_..." }
        }
      }
    }

    Or an Authorization: Bearer aw_live_... header if your client speaks remote HTTP. add over an existing name is the step people skip, so remove first:

    claude mcp remove attestwire
    claude mcp add --transport http attestwire https://api.attestwire.com/mcp \
      --header "Authorization: Bearer aw_live_..."
  2. Restart or reconnect the MCP server. Editing the config of a running client changes nothing until it reconnects.

  3. Verify with one metered call — validate_invoice on any invoice.

Four of the nine tools need a key, not three: the three document tools — validate_invoice, validate_invoice_xml and generate_invoice, which are the metered ones — plus get_upgrade_link, which is keyed but free, because it has to know which key it is quoting an upgrade for. Called without one, the three document tools return an error naming issue_api_key as the remedy and spelling out these steps.

Do not mint twice: the limit is one free key per email address, so a second call answers 409 rather than issuing a replacement. If a metered call still fails after the reconnect, the problem is the config, not the key.

| Variable | | |---|---| | ATTESTWIRE_API_KEY | Optional. Needed by validate_invoice, validate_invoice_xml, generate_invoice and get_upgrade_link; the other five tools ignore it. | | ATTESTWIRE_MCP_URL | Optional endpoint override. Defaults to https://api.attestwire.com/mcp. |

Tools

You can hand these tools a JSON invoice model or an XML invoice file. Both of the syntaxes EN 16931 is written in are read and written: UBL 2.1 Invoice, UBL 2.1 CreditNote and UN/CEFACT CII CrossIndustryInvoice, which carries invoices and credit notes alike. What is not read or written is a PDF. See what this does not do.

| Tool | Key? | | |---|---|---| | explain_rule | free | One rule id (BR-DE-15, BR-CO-15, PEPPOL-EN16931-R010…) in plain English: what it requires, the business term it constrains, a fix and an example. 270 rules explained at time of writing — most, not all, of what the validator checks; the live number is in the tool's own description. | | check_vies_status | free | Is VIES (EU VAT number validation) up? Overall or per member state, with latency and 24h/7d uptime. Tells a bad VAT number apart from a down endpoint. | | check_french_readiness | free | Look up a French company by SIREN, SIRET or name in INSEE SIRENE open data. | | list_approved_platforms | free | The DGFiP-approved French platforms (Plateformes Agréées, ex-PDP). | | issue_api_key | free | Mint a free key — 100 documents/month, no signup flow, no card. Minting alone does not authenticate the connection: save, configure, reconnect (§3). | | validate_invoice | key · 1 doc | Check a JSON invoice object against EN 16931 plus the national CIUS. Every failure comes back as a teaching error: rule id, business term, what the rule requires, a concrete fix, and the XPath the rule would have landed on. | | validate_invoice_xml | key · 1 doc | Check an invoice file the user already has — a UBL 2.1 Invoice, a UBL 2.1 CreditNote, or a UN/CEFACT CII CrossIndustryInvoice (invoice or credit note alike). Same teaching errors, plus which syntax it read, the document's BT-24/BT-23, and everything in the file that did not reach the invoice model. Send the file as-is: the reader and the document type are both chosen from the root element. A credit note is not refused. Not a PDF reader. | | generate_invoice | key · 1 doc | Emit compliant XML from a JSON invoice object. The profile chooses the syntax: xrechnung-cii and facturx-en16931 come back as CII, everything else as UBL 2.1. invoiceTypeCode 381 emits a credit note in either syntax. Refuses an invalid invoice rather than emitting XML that passes nothing. | | get_upgrade_link | key · free | A checkout link (Paddle-hosted) for a paid plan. Returns a link; a human still has to open it. |

Four honest limits, stated up front

  • XML, never PDF — in either direction. Factur-X and ZUGFeRD are CII XML inside a PDF/A-3 container. These tools handle the XML. They do not parse a Factur-X or ZUGFeRD PDF, and they do not build one: no container, no factur-x.xml attachment, no /AFRelationship. If you have a PDF, extract the XML from it first. If you need a PDF, pass our XML to a Factur-X packaging library. A facturx-en16931 result is the payload, not a Factur-X document.
  • The two CII profiles are not equally evidenced, and neither is checked per call. The generator's xrechnung-cii fixture documents are run through the official KoSIT validator on release and accepted. The facturx-en16931 ones are not: that profile's BT-24 is the core EN 16931 one, which matches no XRechnung scenario, so KoSIT answers "no scenario matched" rather than passing or failing them — and an absence of a verdict is not a pass. Neither case says anything about the document you generate: nothing is sent to KoSIT at call time.
  • Credit notes yes; debit notes no, and one business term does not survive one. A credit note is a first-class document in both syntaxes now: invoiceTypeCode: "381" emits a UBL CreditNote or a CII document with ram:TypeCode 381, the reader picks the document type off the root element, and the whole rule set runs on it unchanged. What is still refused is ubl:DebitNote, for which EN 16931 has no binding at all. And BT-11, the project reference, has no element in UBL-CreditNote-2.1.xsd, so no conformant UBL credit note can carry one: it is dropped and reported rather than emitted somewhere it does not belong. Reading a file is also a pre-flight, not a verdict from the receiver: validate_invoice_xml checks the model it read, not the XML a receiving platform judges, so a file that passes can still be rejected.
  • check_french_readiness cannot confirm that a company has registered with an approved platform — that lives only in the CAPTCHA-protected DGFiP annuaire, which has no open API. The tool says so in every response.

One smaller gap, for completeness: the 25 arithmetic and decimal-precision rules the validator fires (BR-45/46/48, BR-CO-18, BR-DEC-19/20/23, and the per-category -01 and -09 families) have no plain-English write-up yet. BR-12BR-15 were on that list until @attestwire/en16931 0.6.0 and are not any more: a document read from XML can omit a total it is required to state, so the four presence rules became reachable and now have harvested write-ups like any other rule. None of them can be tripped by anything a caller sends: they constrain the library's own computed arithmetic, which is what they are for. explain_rule says so for those ids and links the rule reference, which does cover them.

Most people do not need this package

Attestwire is a remote MCP server at https://api.attestwire.com/mcp. Any client that speaks streamable HTTP should point at it directly — that is the claude mcp add --transport http line in the quickstart.

This package exists for clients that can only spawn a local stdio process. It moves JSON-RPC messages between stdio and HTTPS and does nothing else: no schema validation, no caching, no interpretation. New tools appear without updating it.

Notes

  • The key is never a tool argument on a metered tool — it is read from the connection. get_upgrade_link is the one exception: it accepts an optional key, so a key minted a minute ago can be upgraded before it has been configured anywhere. Prefer the header even there, because an argument is written into the agent's transcript.
  • Zero runtime dependencies. Node ≥ 20.
  • Diagnostics go to stderr; stdout carries protocol messages only.
  • --help, --version.
  • Free tier is 100 documents/month. validate_invoice, validate_invoice_xml and generate_invoice cost one document each; nothing else costs anything. A file that cannot be read at all — a PDF, a ubl:DebitNote, malformed bytes — never reaches the rules and costs nothing.

MIT · attestwire.com · docs · changelog · [email protected]