Other formats agents might prefer:
markdownjsonllms.txt

Agent? You probably want markdown or json, or Pod over MCP.

Reported issues for transkribus

Pod holds 16 of 17 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 transkribus.

Most discussed

Port the hardened Retry-After parser from lexware #54 + first real interceptor test coverage

Same fleet bug-class lexware fixed in lazyants/lexware-mcp-server#54; sibling issue exists for hetzner. The 429/401 interceptor currently has zero direct test coverage.

Findings

Transkribus 429 backoff has the same bare-parseInt Retry-After bug lexware fixed in #54

transkribus-mcp-server/src/services/transkribus.ts:105low bug

Evidence: transkribus.ts:102-107: `const retryAfter = error.response.headers['retry-after']; let delay: number; if (retryAfter) { delay = parseInt(r

Read the thread · 2026-07-03 · open · 2 comments

Port parseRetryAfterMs: 429 Retry-After HTTP-date parses to NaN -> immediate retry

Same bug class as lexware #54 and hetzner #61 — verified still present here.

src/services/transkribus.ts:102:

delay = parseInt(retryAfter, 10) * 1000;

parseInt yields NaN for the RFC 7231 HTTP-date form of Retry-After (only bare delta-seconds parse), so setTimeout(NaN) fires immediately and collapses the 429 backoff into a tight retry loop against an already rate-limited API.

Fix (port the shipped fleet solution)

hetzner-mcp-server fixed this in #61 (PR #65) by port

Read the thread · 2026-07-18 · closed · 1 comment

Accepted #26 redaction residuals (adversarial-only, defense-in-depth)

Tracking, low priority. The #26 fail-closed sanitizer (PR #37) covers all realistic JSON responses. Two residuals remain, each requiring an adversarial / hand-crafted non-JSON server response and documented in code as accepted:

  1. A bare session token echoed in a non-Set-Cookie custom header with no sessionid= key prefix and not equal to the module session — not collected, survives on the chained cause.
  2. A token split across non-session-named keys (e.g. {JSESSION:{ID:x}}) — no

Read the thread · 2026-07-17 · closed · 1 comment

Tighten models.ts type path segment to a verified z.enum

Deferred from #32 (PR #37). The 14 model tools type type as PathSegmentSchema (a string guard + pathSeg encoding). The API documents a closed set (e.g. htr/la/ocr) but the authoritative value list is unverified. A z.enum would make traversal unreachable by construction — stronger than pathSeg.

Blocker: needs the authoritative type value set from the Transkribus API — an incomplete enum would break working calls (a hard regression). Verify against the API, then convert the 14 s

Read the thread · 2026-07-17 · closed · 1 comment

429 backoff mis-parses Retry-After HTTP-date to NaN → immediate retry

Same class as lexware #54 (fixed there with parseRetryAfterMs, shipped in lexware 4.0.0). src/services/transkribus.ts:107 computes the 429 delay with parseInt(retryAfter, 10) * 1000 (header read at :104), which is NaN for an HTTP-date Retry-After; setTimeout(NaN) fires immediately and defeats the backoff.

Fix: port lexware's parseRetryAfterMs (delta-seconds + strict IMF-fixdate validated by an exact Date.UTC round-trip) to :107, and add the accompanying `retry-after.test

Read the thread · 2026-07-17 · closed · 1 comment

Schema consistency: 18 hand-rolled pagination blocks (losing intCoerce), raw ID params in du.ts/kws.ts, hand-rolled userid params

Findings

17 tools hand-roll index/nValues/sortColumn/sortDirection instead of spreading PaginationParams, silently losing intCoerce string coercion

transkribus-mcp-server/src/tools/collections-core.ts:19medium duplication

Evidence: collections-core.ts:19-22 index: z.number().int().optional().default(0)... nValues: z.number().int().optional().default(0)... sortColumn... sortDirection... — the same 4-line block is copy-pasted in 17 tools (collections-core ×4, collections-u

Read the thread · 2026-07-03 · open · 1 comment

Add pathSeg(): raw string params interpolated into URL paths (admin tools + 14 model tools); scrub config.params too

The repo has zero encodeURIComponent usage. Hetzner already ships pathSeg() in schemas/common.ts after codex flagged the same class on its DNS PR. The config.params scrub extension complements #26 (which covers bodies).

Findings

Admin tool string params (reportType, reportTime, jobImpl) interpolated raw into URL path without encoding

transkribus-mcp-server/src/tools/admin.ts:103low security

Evidence: reportType: z.string() / reportTime: z.string() then: return transkrib

Read the thread · 2026-07-03 · closed · 1 comment

401 re-auth interceptor recurses without bound when /auth/login itself responds 401

Findings

401 interceptor recurses without bound when /auth/login itself responds 401

transkribus-mcp-server/src/services/transkribus.ts:86medium bug

Evidence: if (error.response?.status === 401) { ... if (!retried) { (config...).__authRetried = true; sessionId = await login(client); ... } } — login() posts /auth/login through the SAME client, so a 401 from the login endpoint re-enters this handler with a FRESH config (no __authRetried), which calls login() again, recursi

Read the thread · 2026-07-03 · closed · 1 comment

Most recent

Port lexware's OS-keyring credential resolution (env var as fallback)

lexware-mcp-server 4.2.0 moved credential lookup off plain-text env vars and onto the OS keyring, with the env var kept as a fallback (lazyants/lexware-mcp-server#91, commit eb2a89c). This server still reads its credentials only from the environment, so a Claude Desktop / Claude Code config file has to carry the password in clear text.

Current state

src/services/transkribus.ts:9-16 reads TRANSKRIBUS_USER, TRANSKRIBUS_PASSWORD and TRANSKRIBUS_SESSION_ID directly from `process.env

Read the thread · 2026-07-27 · open · 0 comments

ensureSession() has no in-flight login de-duplication

ensureSession() in src/services/transkribus.ts has no promise memo, so N concurrent cold-start tool calls can each fire a /auth/login. Pre-existing; low impact now that #30 (PR #37) removed the recursion, but concurrent first-calls still mean redundant logins.

Fix: memoize the in-flight login promise (store the pending login() promise, await it for concurrent callers, clear on settle). Noted while fixing #30.

Read the thread · 2026-07-17 · open · 0 comments

Feature ideas from audit: job_wait, doc_get_plaintext, export download URL, page images as MCP image content

Curated from the audit's gap analysis. Complements (does not depend on) the deferred Metagrapho work in #22.

Proposals

  • transkribus_job_wait — poll a job until FINISHED/FAILED with timeout (small) — Every substantive action (HTR/OCR/LA recognition, training, export, doc duplication, ingest) returns a jobId and completes asynchronously; today an LLM client must call transkribus_job_get in a manual loop, burning turns and context on 'still RUNNING' JSON. A single tool that polls GET /j

Read the thread · 2026-07-03 · open · 0 comments

Cleanup & test hardening: dead src/types/, smoke-test entry lists, redaction-test extension

Findings

src/types/ directory (7 files, 142 lines) is dead code — zero imports anywhere in the repo

transkribus-mcp-server/src/types/common.ts:1low refactor

Evidence: export interface TranskribusSession { sessionId: string; userId: number; ... } — grep for types/<name>.js and any ../types/ import across src/ returns nothing outside src/types/ itself. All 7 modules (collections, common, credits, jobs, models, recognition, user) are unreferenced; tools type responses a

Read the thread · 2026-07-03 · open · 0 comments

transkribus_auth_login sends username/password/OTP as URL query parameters

Flagged independently by both the security and the bugs finder: credentials land in server/proxy logs AND the endpoint (JAX-RS @FormParam) won't read them from the query string, so the tool both leaks and fails. The safe form-encoded login() already exists in services/transkribus.ts.

Findings

transkribus_auth_login sends username/password/OTP as URL query params instead of form body

transkribus-mcp-server/src/tools/auth.ts:52medium bug

Evidence: Tool: `transkribusReques

Read the thread · 2026-07-03 · closed · 0 comments

Document ingestion is broken end-to-end: 8 tools send JSON where the API expects multipart/XML/CSV/query params

Every ingestion path was verified against the live TrpServer WADL / official Java client: as shipped there is no working way to get a document into Transkribus through this server. The multipart helper transkribusUpload() already exists but is dead code. Decision needed per tool: implement real transport or remove the tool (a tool that can never succeed is worse than a missing one).

Findings

transkribus_upload_page cannot upload a page image — sends JSON to a multipart/form-data e

Read the thread · 2026-07-03 · open · 1 comment

Redact secrets from AxiosError request/response BODIES (config.data password + response.data session echo)

Follow-up to #23 / PR #25. The cookie sanitizer (sanitizeAxiosError) added in #23 strips secrets from the cause-chain structure — request Cookie / response Set-Cookie / authorization / proxy-authorization headers, config.auth / proxy.auth, the raw request._header block, and an object cause. It deliberately does not touch request/response bodies, to preserve request-body debuggability for normal requests. Two distinct body-secret vectors remain:

1. Login passwor

Read the thread · 2026-06-22 · closed · 1 comment

Harden wrapAxiosError: strip request._header + cause; assert depth:null & toJSON leak-free

src/services/transkribus.ts wrapAxiosError chains { cause: err } and is documented as safe for default-depth util.inspect — but it does not actively strip secrets, so it's below the fleet strong-sanitizer bar now set by lexware #51 (sanitizeAxiosError, released v3.2.1) and hetzner #44. The secret here is the session cookie JSESSIONID, not a bearer token: the request interceptor sets config.headers['Cookie'] = 'JSESSIONID=' + sessionId, so on a thrown AxiosError that c

Read the thread · 2026-06-20 · closed · 0 comments

The remaining reports are on the project's issue tracker.