v4.0.2
Changelog - v4.0.2
All notable changes to the law-scrapper-mcp project for version v4.0.2 will be documented in this file.
The format is based on Keep a Changelog 1.1.0,
and this project adheres to Semantic Versioning 2.0.0.
[4.0.2] - 2026-09-01
Outbound politeness towards api.sejm.gov.pl — egress rate limiting and concurrent-request budgeting to respect the public API. No MCP tool changes signature or response shape.
Added
- Egress rate limiting — A token bucket now bounds how fast requests leave for the Sejm API, on top of the existing concurrency bound. Configurable with
LAW_MCP_API_RATE_PER_SECOND(default5.0) andLAW_MCP_API_RATE_BURST(default10). ARetry-Aftersent by the API now pauses the whole client rather than each failing request separately, so honouring it no longer ends in a synchronised retry burst. The pause is capped at 60 seconds regardless of the header's requested duration, so a large or misconfiguredRetry-Aftercannot silently wedge every in-flight tool call. Pacing is also bounded byLAW_MCP_API_RETRY_BUDGET: a call that cannot be paced within its own time budget fails immediately with a message naming the pause, instead of waiting out a window it was never going to survive and returning a bare client-side timeout. Retry-Afteris now read in both forms RFC 9110 allows. Only the delta-seconds form was understood before; a date-form header — which the WAF in front of the API may send even though the API itself does not — was discarded, which silently left the client-wide pause switched off. Repeated headers are resolved to the longest wait.- Separate concurrency budget for content downloads —
LAW_MCP_API_MAX_CONCURRENT_CONTENT(default2) governs act HTML and PDF downloads, so a run of document fetches can no longer occupy every slot and stall concurrent searches.
Changed
LAW_MCP_API_MAX_CONCURRENTdefault lowered from10to8, and its meaning narrowed to light JSON requests. Together with the newLAW_MCP_API_MAX_CONCURRENT_CONTENTof2the peak concurrency the API sees is unchanged at ten. Deployments that relied on the default now get eight light slots plus two heavy ones; set both variables explicitly to restore any other split.browse_actsfetches one page instead of a whole year. It now queriesacts/searchwithlimitandoffsetrather thanacts/{publisher}/{year}, which ignores both and returns the full year every time — 1 093 224 B and 1984 records forDU/2024, of which a default page kept twenty. Results, ordering and response fields are unchanged. Abrowse_actscall with a non-numericyearnow returns a clean tool error instead of silently queryingyear=0.limitis now clamped to the same maximum of 100 items every other list tool applies, because it reaches the API and decides the page width where the year endpoint used to ignore it; a negativelimitoroffsetreturns a clean tool error instead of being silently dropped.search_legal_actsandbrowse_actsnow query the sameacts/searchendpoint, which makes a pre-existing asymmetry newly visible:search_legal_actsstill reportstotal_countas the size of the current page, whilebrowse_actscorrectly reports the size of the whole year.