Releases: 4lador/leantime-mcp
Releases · 4lador/leantime-mcp
Release list
v2.8.0
v2.7.0
feat: idempotency keys on creation tools — safe agent retries An optional idempotencyKey on the six creation tools lets an agent retry a call whose response was lost on its side (harness timeout, session restart, retry loop): a retried call with an already-succeeded key returns the original result, marked idempotentReplay: true, with zero write requests. - journal: one file per instance profile (idempotency.json, 0600, atomic temp+rename writes, TTL 7 days — LEANTIME_MCP_IDEMPOTENCY_TTL_DAYS, 0 disables expiry — capped at 10k live entries with an actionable error); survives process restarts; corrupt files read as empty rather than breaking mutations - scoping: (instance, tool, key) — cross-tool reuse is refused with an actionable error instead of a false hit; failed mutations do not consume their key; dry runs ignore keys entirely (and consume nothing) - gate placement: replay short-circuits before any API call, including validation reads — a replay costs zero requests - honest scope (in the CHANGELOG and the module doc): keys cover agent-driven retries, NOT Ambiguous 5xx outcomes — a lost server response leaves nothing to journal, those still instruct verify-first - client: with_idempotency_dir() pins the journal base; the serve command resolves it from the active instance profile (keyring root fallback when running on pure env credentials) Also in this release (separate commit): CI contract tests against Leantime :latest for API drift detection. Tests: 5 unit (validation bounds, round-trip hit/miss/mismatch, TTL, corrupt-file recovery, on-disk parseability) + 5 integration via mockito (replay = exactly one mutation wire-wide, failure doesn't consume the key, cross-tool reuse refused, dry-run ignores keys, bulk batch replays as a whole).
v2.6.0
chore: v2.6.0 — 5xx ambiguity fix + documentation honesty pass + READ…
v2.5.4
docs: overhaul — What's new removed for good, v1.x migration in its o…
v2.5.3
fix: publish job needs the crates-io-auth-action — cargo does no OIDC…
v2.5.2
chore: v2.5.2 — CI verification release First end-to-end run of the tag-triggered publish job: crates.io via keyless trusted publishing, MCP Registry via OIDC. No functional changes — exists to prove the automation before a genuine release depends on it.
v2.5.1
chore: v2.5.1 — docs-only release, sync the crates.io README The crates.io page renders the README embedded at publish time; the consolidated What's-new and badges landed after the 2.5.0 upload. This patch release republishes with current docs. server.json follows to 2.5.1.
v2.5.0
feat: concurrent comment harvesting for --full backups LEANTIME_MCP_BACKUP_CONCURRENCY (1-8, default 1): the per-ticket comment calls run with bounded concurrency through the shared HTTP pool. Default stays sequential — on rate-limited instances concurrency buys nothing (the reactive 429 backoff governs throughput regardless, live-observed: C=4 on a 10/min instance is slower from retry collisions); on generous instances N>1 removes round-trip latency. Results are collected in INPUT order — the backup file is identical whatever the concurrency (live-verified C=1 vs C=4, same comments in the same order). To keep the sequential and concurrent paths from ever diverging, the request/retry policy (429 <=5 with server-hinted delays, 502/503/504 <=2, 64 MB response cap) was extracted into request_with_retries over rpc_roundtrip — one implementation shared by call() and the spawned concurrent requests. Tests: order preservation under concurrency, measured speedup via a minimal delay HTTP server (mockito can't delay), C=1 serialization floor, per-ticket 429 retry.
v2.4.0
feat: date-window pagination — completeness fetches immune to the API…
v2.3.3
fix: list_tickets status label filter resolved the wrong result set The label was passed raw to the API, which intval()s it: "New" became 0 and silently filtered on status ID 0 — asking for New returned every Done ticket on the local test project (175 items, live-reproduced). Labels now resolve to IDs server-side against the project's cached status map (case-insensitive); CSV lists resolve token by token; unknown labels error with the project's valid statuses (id + name); the server's magic done/not_done values and numeric IDs pass through untouched. Live-verified: status="New" → 101 New items (was 175 Done); unknown label → actionable error listing valid statuses.