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.2.2

Published

stdio bridge to the Attestwire MCP server — fourteen e-invoicing tools, including reviewed invoice repair, Peppol recipient lookup and live VIES verification: validate invoice data, a UBL 2.1 / UN-CEFACT CII invoice file, or a Factur-X / ZUGFeRD PDF, agai

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.

Six of the fourteen 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 | 14 — 6 keyless, 7 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. 321 rule ids explained in plain English — every rule id the validator can report. | | Reads / writes | UBL 2.1 Invoice, UBL 2.1 CreditNote, UN/CEFACT CII CrossIndustryInvoice, in both directions. Also reads a Factur-X / ZUGFeRD PDF; never writes one. | | 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). | | Paid plans | Solo €9/mo for 1,000 documents, Starter €29/mo for 5,000, Scale €99/mo for 50,000, or €290 and €990 a year for Starter and Scale billed yearly. get_upgrade_link returns the checkout link; a human opens it and pays. Every metered result reports the documents left and the reset date, and the call that crosses 80% carries a one-time notice naming the next plan. Plans and quotas. | | 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 reads a Factur-X or ZUGFeRD PDF — CII XML inside a PDF/A-3 container — and never builds one: no container, no factur-x.xml attachment, no /AFRelationship. 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. Five other tools work the same way with no key: check_vies_status, check_french_readiness, list_approved_platforms, issue_api_key and send_feedback.

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.

Eight of the fourteen tools need a key: seven metered checks plus get_upgrade_link, which is keyed but free. Completed checks use one document; unavailable live checks are uncharged. The live check tools send the relevant identifier to VIES or OpenPeppol. Evidence is returned to the caller, not stored. See the preflight documentation.

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, diagnose_invoice, lookup_peppol_participant, verify_vat_vies, get_recipient_profile and get_upgrade_link; the other six 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, an XML invoice file, or a Factur-X / ZUGFeRD PDF. 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. A PDF is read too, for the XML attached inside it; nothing here writes one. 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. 321 rules explained at time of writing — every rule id the validator can report; 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). | | send_feedback | free | Tell the people who build this what the user was trying to do when no tool here does it, or a result looked wrong or confusing. The goal in the agent's words, never invoice data; identifiers are scrubbed before storage, and nobody can reply to it. | | 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, a UN/CEFACT CII CrossIndustryInvoice (invoice or credit note alike), or a Factur-X / ZUGFeRD PDF. 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. A PDF's attachment and XMP metadata are checked too, as findings that never fail it; PDF/A conformance and whether the page agrees with the XML are not. Send XML as text and a PDF base64-encoded; a credit note is not refused. | | 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. | | diagnose_invoice | key · 1 doc | Diagnose JSON/XML and provider rejection text/SVRL; apply explicitly reviewed revisions and revalidate. | | lookup_peppol_participant | key · 1 doc | Check exact recipient and advertised document support through OpenPeppol. Unavailable results are uncharged; registration does not prove delivery. | | verify_vat_vies | key · 1 doc | Dated VIES observation: valid, invalid, or unavailable. Unavailable results are uncharged. | | get_recipient_profile | key · 1 doc | From the buyer's country and one identifier (VAT id, Leitweg-ID, SIREN/SIRET, KBO number, GLN or Peppol id): how to invoice them — channel, format, and the fields the invoice needs — checked against VIES, OpenPeppol and the French register. Uncharged when the identifier fails its own check digits or every source is unavailable. | | get_upgrade_link | key · free | A checkout link (Paddle-hosted) for a paid plan (see the table above). Returns a link; a human still has to open it. |

Four honest limits, stated up front

  • Reads a Factur-X or ZUGFeRD PDF now; still never writes one. Factur-X and ZUGFeRD are CII XML inside a PDF/A-3 container. validate_invoice_xml reads one — send the file's bytes base64-encoded in pdf_base64, capped at 1 MB (about 750 KB of PDF); a larger file goes to POST /v1/validate over the HTTP API instead. It checks the attachment and the XMP metadata too, as findings that never fail the result; PDF/A conformance itself, and whether the drawn page agrees with the XML, are not checked. No tool here builds a PDF — no container, no factur-x.xml attachment, no /AFRelationship — though the HTTP API does, on every plan (POST /v1/generate?format=pdf with profile facturx-en16931), watermarked as a preview on the free plan. A facturx-en16931 result from these tools 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.

explain_rule has a write-up for every rule id the validator can report. That is not every rule of the official schematrons: the validator does not implement all of them (the engine README lists what is excluded), and a rule it does not implement has nothing to explain here.

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; Solo €9/mo for 1,000 documents, Starter €29/mo for 5,000, Scale €99/mo for 50,000 (€290 and €990 a year for Starter and Scale if billed yearly). validate_invoice, validate_invoice_xml, generate_invoice and diagnose_invoice cost one document each; lookup_peppol_participant and verify_vat_vies cost one per conclusive result and nothing when the outside service is unavailable; nothing else costs anything. Each metered result ends with the documents left, the plan and the reset date, and the call that crosses 80% of the allowance carries a one-time notice naming the next plan. A file that cannot be read at all — a PDF with no invoice XML attached, a ubl:DebitNote, malformed bytes — never reaches the rules and costs nothing.

Trademark

"Attestwire"™ and the Attestwire logo are trademarks of this project's owner. The MIT licence covers this package's code and grants no trademark rights. You may say your product uses or is built on it; you may not name or brand a product or service "Attestwire", or imply that we endorse yours.

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