New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@kontor-mcp/server

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kontor-mcp/server

Kontor MCP server — sovereign e-invoice tools for AI agents over stdio and Streamable HTTP

latest
Source
npmnpm
Version
1.0.4
Version published
Weekly downloads
34
-46.03%
Maintainers
1
Weekly downloads
 
Created
Source

@kontor-mcp/server

Sovereign MCP server for German/EU e-invoices (XRechnung, ZUGFeRD/Factur-X, EN 16931): parse, validate and explain — 100 % offline, no Java, no network.

Tools (v0.9)

ToolPurpose
parse_invoiceDetect format (UBL/CII · EN 16931 · XRechnung version/variant · ZUGFeRD profile) and return the EN 16931 semantic model
validate_invoiceXSD + official EN 16931 / XRechnung Schematron with the KoSIT scenario model → valid / valid_with_warnings / invalid, findings with DE/EN explanations and fix hints
audit_invoiceOne call for AP: parse + validate + Kontor plausibility (totals recomputed, VAT rates, IBAN, Leitweg-ID check digits, dates, known_invoice_numbers duplicates) → header facts, VAT breakdown, verdict, grouped findings, accept / review / reject with rationale
generate_invoiceStructured data → compliant XRechnung 3.0 (UBL) or, with target: zugferd-pdf, a ZUGFeRD 2.3 / Factur-X PDF/A-3 (zugferd_profile EN16931 / BASIC / EXTENDED, embedded factur-x.xml, veraPDF- and Mustang-verified): decimal-safe amounts/VAT/totals, internal validation (fail-honest valid — for PDFs the XML is read back out of the file first), deterministic auto-fixes reported, optional output_path (.xml / .pdf, never overwrites unless overwrite=true), otherwise pdf_base64
convert_invoiceextract-xml (ZUGFeRD PDF → XML), xrechnung-ubl / cii via the semantic model with post-validation and an honest lossReport, html-preview (self-contained HTML, no scripts/assets); optional output_path
check_obligationsOffline decision tree over the German mandate (§ 14 / § 27 Abs. 38 UStG, UStDV §§ 33/34/34a, E-RechV): issuer/receiver × B2B/B2G/B2C, transition 2026 → 2027 (€800k) → 2028, exemptions, formats, Leitweg-ID — with primary sources, lastVerified and a non-advice disclaimer
list_capabilitiesIntrospection: formats/profiles, bundled standard versions, KB stats, code lists, legal lastVerified, tools/resources/prompts, sovereignty statement
explain_ruleExplain a rule id such as BR-DE-15 (official text, explanation, affected BTs, fix hint); unknown ids get suggestions

Every document tool accepts either file_path (absolute; .xml/.pdf; ≤ 20 MB, KONTOR_MAX_FILE_MB) or content_base64 (+ optional content_type), and lang: "de" | "en" (default de).

Resources: kontor://samples/{name} — bundled sample invoices (valid-xrechnung-ubl.xml, valid-xrechnung-cii.xml, broken-missing-buyer-reference.xml, valid-zugferd-en16931.pdf, generated-zugferd-en16931.pdf).

Claude Desktop

claude_desktop_config.json (Settings → Developer → Edit Config):

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

From a local checkout (before the npm publish):

{
  "mcpServers": {
    "kontor": {
      "command": "node",
      "args": ["/absolute/path/to/kontor-mcp/packages/server/dist/bin.js"]
    }
  }
}

Use an absolute path to node (which node) if Desktop cannot find it — it launches servers with a minimal PATH. Quit Desktop fully (⌘Q) and reopen; the config is read at launch. Logs: ~/Library/Logs/Claude/mcp-server-kontor.log.

Restart Claude Desktop, attach an invoice (or +Add from kontorbroken-missing-buyer-reference.xml) and ask "Ist diese Rechnung gültig?".

All tools are offline and stateless; all except generate_invoice / convert_invoice (which may write a file when output_path is given) are read-only (readOnlyHint), so it is safe to set them to Always allow under Settings → Connectors → kontor; on first use Desktop shows a "Needs approval" prompt otherwise.

PDFs: Desktop does not hand attached PDF bytes to the server, so reference ZUGFeRD/Factur-X PDFs by local path instead: "Was steht in dieser Rechnung? /path/to/invoice.pdf". XML attachments work either way (the model re-sends them as content_base64).

Claude Code

claude mcp add kontor -- node /absolute/path/to/kontor-mcp/packages/server/dist/bin.js

MCP Inspector

npx @modelcontextprotocol/inspector@latest node packages/server/dist/bin.js
# or headless:
npx @modelcontextprotocol/inspector@latest --cli node packages/server/dist/bin.js --method tools/list

Streamable HTTP

The same server over HTTP (MCP Streamable HTTP, endpoint /mcp) for remote agents, Docker and clients that cannot hand attachment bytes to a stdio server:

KONTOR_TRANSPORT=http KONTOR_AUTH_TOKEN="$(openssl rand -hex 24)" node packages/server/dist/bin.js
# → [kontor-mcp] kontor-mcp 0.9.0 listening on http://127.0.0.1:3333/mcp (auth: bearer, origins: localhost)
npx @modelcontextprotocol/inspector@latest --cli http://127.0.0.1:3333/mcp --transport http \
  --header "Authorization: Bearer $KONTOR_AUTH_TOKEN" --method tools/list
VariableDefaultMeaning
KONTOR_TRANSPORTstdiostdio or http
KONTOR_PORT3333TCP port (0 = ephemeral)
KONTOR_BIND127.0.0.1Bind address. Loopback (127.0.0.1, localhost, ::1) enables Host-header / DNS-rebinding protection
KONTOR_AUTH_TOKENBearer token (≥ 16 chars), compared in constant time. Required in HTTP mode
KONTOR_ALLOW_NO_AUTH1 runs without a token — only honoured on a loopback bind (local experiments)
KONTOR_ALLOWED_ORIGINSComma-separated browser origins allowed in addition to `http(s)://localhost
KONTOR_ALLOWED_HOSTSComma-separated hostnames accepted in the Host header besides loopback (behind a reverse proxy / in a container). On a loopback bind only loopback hosts pass; on 0.0.0.0 without this list the Host header is not checked and the token is the guard
KONTOR_MAX_SESSIONS100Concurrent MCP sessions; beyond it new initialize requests get 503 + Retry-After
KONTOR_SESSION_IDLE_MINUTES30Sessions without a request for this long are closed (clients that never DELETE)
KONTOR_MAX_FILE_MB20Also sizes the JSON body cap (content_base64 inflates by 4/3)

Behaviour: one MCP session per client (Mcp-Session-Id, UUID), DELETE /mcp ends it, unknown ids → 404; GET /healthz (unauthenticated) returns { ok, name, version, sessions } for container health checks; SIGINT/SIGTERM close all sessions, then the listener. Wrong or missing token → 401 with WWW-Authenticate: Bearer. There is no TLS in the server — terminate it in your reverse proxy (Caddy, nginx, Traefik) and forward to the loopback port; see SECURITY.md.

Docker

The image (Dockerfile at the repo root; multi-stage, node:22-alpine, runs as node, ~70 MB, linux/amd64 + linux/arm64) defaults to KONTOR_TRANSPORT=http, KONTOR_BIND=0.0.0.0, port 3333 and refuses to start without KONTOR_AUTH_TOKEN. A HEALTHCHECK polls /healthz. The samples ship at /app/samples/; mount your own invoices read-only (-v ./invoices:/data:ro) and reference them as /data/<file>.

docker build -t kontor-mcp .
docker run -d --name kontor -p 127.0.0.1:3333:3333 -e KONTOR_AUTH_TOKEN="$(openssl rand -hex 24)" -v "$PWD/invoices:/data:ro" kontor-mcp
docker run -i --rm -e KONTOR_TRANSPORT=stdio kontor-mcp        # stdio inside a container also works

docker-compose.yml is a hardened example (loopback-published port, read_only, cap_drop: ALL, no-new-privileges, token from .env). CI builds both platforms and runs an Inspector-over-HTTP smoke test against the image on every push.

Privacy / sovereignty

Stateless; nothing is stored or transmitted; invoice contents are never logged (see PRD NFR-2/NFR-5/NFR-6). Findings are formal/technical checks, not tax or legal advice.

Resources and prompts

URI / nameWhat
kontor://samples/{name}Sample invoices (UBL, CII, ZUGFeRD PDF, one broken)
kontor://reference/rulesRule knowledge-base index (all EN 16931 / XRechnung rule ids, severity, curated flag)
kontor://reference/codelists/{list}units, vat-categories, payment-means, eas, vatex, invoice-types, currencies, countries, allowance-reasons, charge-reasons, identifier-schemes, mime-types, vat-point-date-codes — official code values with DE/EN names for the common ones
kontor://reference/cheatsheetOne-page EN 16931 / XRechnung / ZUGFeRD orientation incl. the German mandate timeline (Markdown)
prompt audit-incoming-invoiceRun audit_invoice and present a decision-ready AP summary
prompt draft-supplier-rejectionDraft (never send) a German rejection e-mail citing the concrete rule violations
prompt create-invoice-interviewInterview for the minimal XRechnung field set, then generate_invoice

Keywords

e-invoice

FAQs

Package last updated on 26 Aug 2026

Related posts