Home
Softono

Lexware Mcp

Open source MIT TypeScript
15
Stars
1
Forks
1
Issues
1
Watchers
3 months
Last Commit

 About Lexware Mcp

Open-source, self-hostable MCP server for the Lexware Office (lexoffice) accounting API — comprehensive coverage: contacts, articles, bookkeeping vouchers, the sales-document family (invoices/quotations/credit-notes, draft + finalize), and file/PDF upload & download. OAuth, Cloud Run; connects to Claude & ChatGPT.

Platforms

Web Self-hosted Cloud

Languages

TypeScript

Links

Need Help Installing Lexware Mcp?

We provide expert installation service for this software. Our team will install, configure, and secure Lexware Mcp on your server. plans start at just $30.

Lexware Mcp

View on GitHub

Lexware Office MCP Server

An open-source, self-hostable MCP server for the Lexware Office accounting API. Run your own instance, connect it to Claude, and let an agent read your invoices, vouchers, contacts and articles — and (optionally) draft new ones.

Bring your own Lexware API key — the server is single-tenant per deployment and never stores anyone else's credentials. It runs as a remote HTTP server on any container host, built with the Skybridge framework.

Two authentication methods — choose one:

  • OAuth 2.1 — required to use this as a web MCP server / custom connector in the Claude app, claude.ai web, or ChatGPT (those clients accept only OAuth).
  • Static bearer token — simpler, but works only with Claude Code / Claude Desktop (which let you send a request header); the web custom-connector UI does not support it.

Setup for both is in the Client support & authentication section below.

Related projects — local (stdio) Lexware MCP servers: lazyants/lexware-mcp-server, JannikWempe/mcp-lexware-office.

⚠️ This brokers real accounting data. Read SECURITY.md, protect your tokens, and note that finalized invoices are legally binding — you are responsible for their tax/legal correctness. No warranty (MIT).

Capabilities

65 tools across three tiers you enable via environment variables:

Tier Default What it covers
Read always on Profile; contacts & articles (list/get); the voucherlist; full documents (invoices, quotations, credit notes, order confirmations, delivery notes, dunnings, down-payment invoices, vouchers); render any document type to PDF and download files/receipts (returned inline as embedded resources); batch & type-dispatched reads (get-vouchers, get-document, get-voucher-file, get-document-file); payments; reference data (countries, payment conditions, posting categories, print layouts); recurring templates (get & list); event subscriptions; document deeplinks
Drafts/writes (LEXWARE_ENABLE_DRAFTS) on Create and update draft invoices/quotations/credit-notes/order-confirmations/delivery-notes/dunnings; create & update contacts, articles, and bookkeeping vouchers; upload files and attach receipts to vouchers; create event subscriptions; optionally issue documents finalized (finalize=true, requires LEXWARE_ENABLE_FINALIZE) or as follow-ups (precedingSalesVoucherId)
Finalize (LEXWARE_ENABLE_FINALIZE) off Issue legally binding finalized documents (confirmation-gated); irreversible deletes (articles, event subscriptions)

Set LEXWARE_READ_ONLY=true to force read-only (overrides the flags above).

Client support & authentication

The server supports two ways to protect /mcp, chosen by environment:

  • OAuth 2.1 (OAUTH_ISSUER, …) — the recommended path. Use any OAuth provider (e.g. WorkOS AuthKit, Stytch, Auth0, Clerk; or self-hosted Keycloak/Zitadel) as the authorization server. This makes the server work as a custom connector in the Claude app, on claude.ai web, and in ChatGPT, with a real sign-in. Optionally restrict access with OAUTH_ALLOWED_EMAIL_DOMAINS (enforced server-side via the token's email / the provider's userinfo endpoint).
  • Static bearer token (MCP_AUTH_TOKEN) — the simpler fallback. Works with Claude Code and Claude Desktop (which let you set a request header), but not the custom connector UI / claude.ai web / ChatGPT (those require OAuth).

OAuth takes precedence when OAUTH_ISSUER is set; otherwise the static token is used. With neither set, the server refuses to start unless MCP_ALLOW_UNAUTHENTICATED=true.

Connecting as a custom connector (OAuth)

  1. In your provider, create an app, enable Dynamic Client Registration (or pre-register Claude's redirect https://claude.ai/api/mcp/auth_callback), and set this server's URL as the Resource Indicator / audience.
  2. Deploy with OAUTH_ISSUER, OAUTH_RESOURCE (= the public URL), and optionally OAUTH_ALLOWED_EMAIL_DOMAINS.
  3. In the Claude app → Connectors → Add custom connector, enter the server URL (https://…/mcp). Claude discovers the authorization server via /.well-known/oauth-protected-resource and walks you through sign-in.

Quick start (Docker)

git clone https://github.com/marselsel/lexware-mcp && cd lexware-mcp
cp .env.example .env          # set LEXWARE_API_KEY and MCP_AUTH_TOKEN
docker compose up --build     # serves on http://localhost:8080/mcp

Generate a strong auth token:

openssl rand -hex 32

Without Docker:

npm install
npm run build
LEXWARE_API_KEY=... MCP_AUTH_TOKEN=... npm start

Configuration

Env var Default Purpose
LEXWARE_API_KEY — (required) Your Lexware API key (create one)
OAUTH_ISSUER OAuth authorization-server issuer URL. Setting it enables OAuth mode¹
OAUTH_RESOURCE / SERVER_URL This server's public URL (token audience / Resource Indicator). Required in OAuth mode
OAUTH_ALLOWED_EMAIL_DOMAINS Comma-separated allow-list of email domains (e.g. example.com)
OAUTH_VERIFY_AUDIENCE true Verify the token aud matches OAUTH_RESOURCE. Keep true. Setting false accepts any valid token from the issuer — including one minted for a different app on the same issuer (a confused-deputy risk). Only disable for a dedicated, single-audience issuer that has no Resource Indicator
MCP_AUTH_TOKEN — (required¹) Static bearer token clients send to reach /mcp (used when OAuth is off)
MCP_ALLOW_UNAUTHENTICATED false Opt out of auth (trusted local use only)
LEXWARE_READ_ONLY false Register only read tools (hard override)
LEXWARE_ENABLE_DRAFTS true Enable create-draft tools
LEXWARE_ENABLE_FINALIZE false Enable finalize / legally-binding tools
LEXWARE_API_BASE_URL https://api.lexware.io API base URL
LEXWARE_APP_BASE_URL https://app.lexware.de Web-app base for document deeplinks
PORT 8080 Listen port (your platform may inject this)
LEXWARE_DEBUG_LOGGING false Verbose logs (never secrets/bodies)

¹ The server needs either OAUTH_ISSUER (OAuth) or MCP_AUTH_TOKEN (static). It refuses to start with neither, unless MCP_ALLOW_UNAUTHENTICATED=true.

Connect to Claude (Code / Desktop)

Add to your MCP config (e.g. ~/.claude.json or the Desktop config):

{
  "mcpServers": {
    "lexware": {
      "type": "http",
      "url": "https://<your-host>/mcp",
      "headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
    }
  }
}

Deploy

The server is a standard Docker container (Dockerfile) — run it on any host that can serve HTTPS (a VPS, Fly.io, Render, Railway, Cloud Run, Kubernetes, …):

docker build -t lexware-mcp .
docker run -p 8080:8080 --env-file .env lexware-mcp

Production notes:

  • Serve over HTTPS (terminate TLS at your platform or a reverse proxy).
  • Set auth via env (OAUTH_ISSUER… or MCP_AUTH_TOKEN) — the server fails closed otherwise.
  • Run a single instance (or cap autoscaling to 1): the ~2 req/s rate limiter is per-process, so multiple instances would aggregate beyond Lexware's limit.
  • Health check: GET /status (returns 200).

Google Cloud Run: a step-by-step recipe (Secret Manager + gcloud run deploy + custom domain) is in docs/cloud-run.md.

How it works

  • src/config.ts — env parsing/validation, fail-closed auth, capability tiers.
  • src/auth.ts — constant-time static-bearer middleware on /mcp.
  • src/lexware/ — rate-limited (~2 req/s, token bucket), retry-aware client with safe error mapping; never retries non-idempotent POSTs on ambiguous failures (no duplicate documents).
  • src/tools/ — tools registered conditionally by tier.
  • src/server.ts — wires it together on the Skybridge Express server.

Development

See CONTRIBUTING.md. npm run dev starts the Skybridge dev server + DevTools at http://localhost:3000.

License

MIT © marselsel.