# 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](/mcp/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`:

```ts
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).
