Reported issues for lexware
Pod holds 18 of 26 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.
Back to lexware.
Most discussed
Decide the fate of the deprecated url alias on lexware_deeplink_contact
Follow-up from #66 (shipped in 4.1.0, PR #76).
Updated 2026-08-20. The original body scheduled this for "the next major (5.0.0)". That gate has already passed — 5.0.0 shipped (16d80a1) and 5.1.0 after it (6989b17), with the alias untouched. Body rewritten so an implementer reads the current state rather than an expired plan.
Current state
To stay backward-compatible under a MINOR bump, lexware_deeplink_contact returns both keys — src/tools/contacts.ts:62:
const deeplin
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/78) · 2026-07-17 · open · 2 comments
### Triage Dependabot dev-dependency alerts
Pushing Wave 1 surfaced Dependabot alerts on the default branch (~1 critical / ~10 high / others). These are **pre-existing dev/transitive** alerts — NOT in the production tree: CI `npm audit --audit-level=moderate --omit=dev` returns **0 vulnerabilities**. Dependabot scans the full tree (incl. devDependencies) while `npm audit --omit=dev` is prod-only — they diverge (see `gotcha_dependabot_stale_alerts`).
**Action:**
- Cross-check Dependabot alerts vs full `npm audit`; confirm each is dev/tran
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/52) · 2026-06-20 · closed · 2 comments
### Decide: enable Dependabot security updates, or record why not (26 alerts open)
> **Updated 2026-08-20.** Re-measured; the premise holds and the numbers have grown. The original four-item checklist has been cut to the one decision that is actually open — see "What was cut and why".
## What
Vulnerability alerts are **enabled**, but automated security fixes are **off**:
GET /repos/lazyants/lexware-mcp-server/vulnerability-alerts -> 204 (enabled) GET /repos/lazyants/lexware-mcp-server/automated-security-fixes -> {"enabled": false, "paused": false}
So GitHub detec
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/99) · 2026-07-27 · open · 1 comment
### Port the Content-Disposition parser and fail-closed sanitizer to hetzner and transkribus
Fleet ripple from the lexware 4.2.0 batch. Cross-ref hetzner #47, and the audit-gate issues already filed as hetzner #71 / transkribus #43.
Two pieces of lexware work are likely relevant to the siblings:
**1. RFC 6266/5987 Content-Disposition parsing** (#63, PR #85)
Only port this if those servers parse the header at all — check before assuming. The lexware version handles the quoted form with spaces, RFC 5987 `filename*` with correct precedence, and reduces the result to a sanitized basename.
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/90) · 2026-07-26 · closed · 1 comment
### Port AxiosError body/params scrub + fail-closed sanitizer from transkribus #26/#32
Fleet ripple from transkribus-mcp-server v3.0.0 (PR #37). `wrapLexwareError`/`sanitizeAxiosError` currently scrub headers/`config.auth` but not request/response **bodies** or query params. transkribus added:
- **`config.data`** (request body) scrub on every request.
- **`config.params` + `config.url`** query-string scrub.
- **Fail-closed** `sanitizeAxiosError` (boolean return): when full redaction can't be guaranteed (bounded-walk cap, a non-plain container, or a throw on a frozen object), call
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/75) · 2026-07-17 · closed · 1 comment
### Feature ideas from audit: finalize param on 4 create tools, voucherlist filters/sort, e-invoice XML download
Curated from the audit's gap analysis against the Lexware API docs.
> **Updated 2026-08-20.** All five original proposals were re-measured against `main` at 5.1.0. Three survive unchanged and are listed below. Two were dropped and are recorded under "Dropped" with the reason, so they are not silently refiled by the next sweep.
## Proposals
- **Add the documented `finalize` param to `create_quotation`, `create_credit_note`, `create_order_confirmation` and `create_delivery_note`** _(small)_ — D
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/70) · 2026-07-03 · open · 1 comment
### Docs drift: README tool inventory 64-vs-67, three deeplink tools missing, LEXWARE_WEBHOOK_PUBLIC_KEY undocumented, SECURITY.md two majors stale
## Findings
### README tool inventory is stale: 64-vs-67 contradiction and the three 3.2.0 deeplink tools are missing from the per-domain lists
`lexware-mcp-server/README.md:37` — **low** bug
**Evidence:** Header says "**67 tools** across 20 resource domains" but the entry-point table says "All 20 domains | 64", bookkeeping "7" and system "10" — smoke.test.ts asserts 67/8/12. Sections "Vouchers (5 tools)", "Files (3 tools)", "Recurring Templates (2 tools)" omit lexware_deeplink_voucher, lexwa
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/68) · 2026-07-03 · closed · 1 comment
### Content-Disposition filename parsing truncates quoted filenames at the first space
Note from verification: the finder's secondary RFC-5987 claim was refuted (filename* falls back gracefully); only the quoted-with-spaces truncation is real.
## Findings
### Content-Disposition filename parsing truncates quoted filenames at the first space
`lexware-mcp-server/src/services/lexware.ts:353` — **low** bug
**Evidence:** `const match = contentDisposition.match(/filename="?([^";\s]+)"?/);` — the character class excludes whitespace even inside the quoted form, so `filename="Rechnung
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/63) · 2026-07-03 · closed · 1 comment
## Most recent
### Publish job pins Node 20, below npm Trusted Publishing's documented Node floor
`.github/workflows/publish-registry.yml:23-36` pins `node-version: 20` and upgrades npm to `^11`. That satisfies the npm-CLI half of Trusted Publishing's requirement (TP landed in npm 11.5+), but npm's [Trusted Publishing documentation](https://docs.npmjs.com/trusted-publishers/) states a Node prerequisite of 22.14+ alongside npm 11.5.1+. The workflow satisfies one half of a two-part requirement.
## Not currently broken — measured
This is a latent risk, not a live failure. Run [30254014252](ht
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/102) · 2026-07-27 · closed · 0 comments
### Revisit TypeScript 7 once typescript-eslint supports it
## Context
Dependabot PR #93 proposed bumping `typescript` to the 7.x line. It cannot be merged: `npm ci` fails with `ERESOLVE` before lint, build or test ever run.
peer typescript@">=4.8.4 <6.1.0" from typescript-eslint@8.64.0 Found: typescript@7.0.2
`--legacy-peer-deps` was rejected as a workaround: CI runs plain `npm ci`, and forcing the peer violation would run the linter against a TypeScript version its parser has never been tested against.
## Disposition
PR #93 is closed, and
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/95) · 2026-07-27 · open · 0 comments
### Interceptor 429 retry is never exercised against a real HTTP stack
Surfaced during the #63/#67/#69/#74/#75 batch.
`src/tests/retry-interceptor.test.ts` now covers the retry policy well — Retry-After-driven delay, exponential fallback, `MAX_RETRIES` exhaustion, `__retryCount` growth, the `!config` guard, non-429 pass-through, the one-shot-stream skip, and that a native `FormData` body **is** retried (#85).
But every one of those drives the captured rejection handler with a **hand-built** `err.config`. Nothing in the suite exercises axios's real per-attempt bod
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/89) · 2026-07-26 · closed · 0 comments
### Add a boundary MimeTypeSchema for the two upload tools
Deliberately deferred from #85 (plan decision D1), filed so it isn't lost.
#85 validates the upload `contentType` **inside `lexwareUpload`** — the chokepoint every caller passes through. That is the load-bearing fix and it is done. What was deferred is a second, earlier layer: a shared `MimeTypeSchema` in `src/schemas/common.ts` wired into `tools/files.ts` and `tools/vouchers.ts`, so a malformed value is rejected at the MCP boundary with a schema error rather than at the service call.
**Why it
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/88) · 2026-07-26 · closed · 0 comments
### Published consumers still resolve a vulnerable @hono/node-server (overrides are root-only)
Split out of #80 at review request.
> **Updated 2026-08-20 — the consumer-facing gap closed upstream, in two independent steps, before anything was changed here.** The original body concluded this "cannot be fixed from here". That was true when written and stopped being true on 2026-07-24. Corrected below; an earlier revision of this update overstated the fix and is superseded.
## What
`npm` honours `overrides` only from the **install root**, never from an installed dependency's manifest. #80
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/81) · 2026-07-26 · closed · 0 comments
### Follow-ups from the 4.0.0 audit batch: native FormData migration + git-aware release-drift guard
Two deferred items surfaced while fixing #58/#62 (PR #72) and #57 (4.0.0 release, PR #73):
### 1. Native FormData migration (from #62)
#62 was fixed by *skipping* retry on one-shot `form-data` streams (the interceptor rejects instead of re-piping a drained body). The cleaner fix is to drop the `form-data` package for Node 20's global `FormData` + `Blob` (our `engines.node` floor is 20), which axios rebuilds per request — making upload bodies natively replayable, so the 429 retry would just work
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/74) · 2026-07-17 · closed · 0 comments
### Cleanup & test hardening: 429-interceptor coverage, dead src/types/, download-helper dedup, tautological tests
Bundle of intra-repo quality findings; each is small, they share files, so one PR (or a short series) can take the batch.
## Findings
### 429 retry interceptor logic has zero direct test coverage
`lexware-mcp-server/src/tests/lexware-client.test.ts:42` — **medium** test-gap
**Evidence:** lexware-client.test.ts:42 stubs the interceptor away: `interceptors: { response: { use: vi.fn() } }`. The retry policy in services/lexware.ts:102-126 (`__retryCount` tracking, `parseRetryAfterMs(error.respon
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/69) · 2026-07-03 · closed · 0 comments
### Constrain upload contentType — CRLF injection into multipart part headers (reproduced)
## Findings
### User-supplied contentType flows unescaped into multipart part header (CRLF injection into request body)
`lexware-mcp-server/src/services/lexware.ts:265` — **low** security
**Evidence:** lexware.ts:265 `form.append('file', fileBuffer, { filename: fileName, contentType });` — contentType comes verbatim from tool input (files.ts:25, vouchers.ts:100: `params.contentType || 'application/pdf'`). form-data 4.0.6 escapes CR/LF only for name/filename ("Escape CR, LF, and `\"` in a mult
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/67) · 2026-07-03 · closed · 0 comments
### lexware_deeplink_contact returns { url } while the ten other deeplink tools return { deeplink }
## Findings
### Contact deeplink tool returns { url } while all nine other deeplink tools return { deeplink }
`lexware-mcp-server/src/tools/contacts.ts:61` — **low** bug
**Evidence:** contacts.ts: `const url = `${LEXWARE_APP_BASE}/permalink/contacts/view/${params.id}`; return { url };` — every other deeplink tool (invoices.ts:140, vouchers.ts:116, files.ts:78, dunnings.ts:103, etc.) returns `{ deeplink: ... }`. contacts.test.ts:138 locks in `structuredContent.url`, so the divergence is test-e
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/66) · 2026-07-03 · closed · 0 comments
### Remove undocumented filters the API ignores: contacts `archived`, vouchers `voucherStatus`
## Findings
### lexware_list_contacts exposes an 'archived' filter the contacts API does not document — filtered results are not actually filtered
`lexware-mcp-server/src/tools/contacts.ts:19` — **low** bug
**Evidence:** `archived: z.boolean().optional().describe('Filter by archived status')` is forwarded to GET /contacts, but the docs' "Filtering Contacts" table lists only email, name, number, customer, vendor. An unknown param is ignored or rejected — either way an LLM passing archived=fals
[Read the thread](https://github.com/lazyants/lexware-mcp-server/issues/65) · 2026-07-03 · closed · 0 comments
The remaining reports are on [the project's issue tracker](https://github.com/lazyants/lexware-mcp-server/issues).