v0.2.4
[v0.2.4] — 2026-07-30
Fixed
-
The User-Agent reports the actual package version again. The published
0.2.3sentopenlex-mcp/0.2.0to every upstream — the version string was
hardcoded and had been left behind by earlier bumps. The version now comes
from the package metadata, so it can no longer drift from the package. -
HTTP-Modus wies unter jedem echten Hostnamen mit 421 ab (SEC-005).
_build_http_app()riefmcp.streamable_http_app()ohnehostauf. Unter
mcp 2.x ist das kein neutraler Default: das SDK leitet daraus eine Allow-List
ab und aktiviert bei loopback-artigem Wert automatisch127.0.0.1:*. Da der
Default127.0.0.1ist, galt das auch für denMCP_HOST=0.0.0.0-Bind des
Containers. Nachgemessen an der echten ASGI-App vor dem Fix:Host 127.0.0.1:8000 -> 200 Host mcp.example.ch -> 421 Host openlex.example.com -> 421/healthzantwortete weiter mit 200 und verdeckte es, weshalb ein
Readiness-Probe nichts gemerkt hätte.Der Bind reist jetzt in die App, und eine explizite Allow-List wird aus dem
neuenMCP_ALLOWED_HOSTSgebaut. Ohne diese Variable bleibt der Schutz auf
einem Nicht-Loopback-Bind bewusst aus und der Aufrufer warnt — eine geratene
Liste würde genau das 421-Problem reproduzieren. Konfigurierte CORS-Origins
werden mit aufgenommen, sonst weist der Transport genau die Browser-Clients
ab, die CORS erlaubt.13 neue Tests, davon der tragende „richtiger Hostname, falscher Port": nur er
unterscheidet eine portgenaue Allow-List von einer, die alles durchlässt —
evil.example.comallein würde auch ein zurückfallender Loopback-Default
abweisen. Mutationsgetestet: nimmt man denhost-Kwarg wieder weg,
reproduziert der Test das 421 exakt.Geprüft mit dem wörtlichen CI-Kommando: 111 passed, 8 deselected;
ruff check src/ tests/clean.
Added
- Security policy —
SECURITY.md(English) andSECURITY.de.md(German),
linked from both READMEs andCONTRIBUTING.md. - German contribution guide —
CONTRIBUTING.de.md, linked from
CONTRIBUTING.md.
Fixed
-
Capped
mcpat<2.mcp2.0.0, published 2026-07-28, removed
mcp.server.fastmcp— the module this server imports. With the previous
unbounded>=1.28.1every fresh resolve picked 2.0.0 and failed at import
withModuleNotFoundError, in CI and for anyone runningpip installalike.
Verified in both directions: 2.0.0 fails,<2resolves to 1.29.0 and imports
cleanly. Migrating to the 2.x API (mcp.server.mcpserver) stays a separate,
deliberate piece of work. -
zhlaw_get_law_metadatapermalink — the legacy
http://www.zhlex.zh.ch/Erlass.html?Open&Ordnr=<ordnr>permalink was replaced
upstream and now returns 404 (it redirected to alawcollection-directlink
endpoint that 404s over HTTP). Metadata now resolves via the current
https://www.zhlex.zh.ch/bin/zhweb/publish/lawcollection-directlink?Open&Ordnr=<ordnr>
endpoint, which 302-redirects to the consolidated version onwww.zh.ch. -
Live tests — repaired three nightly live-test regressions caused by upstream
drift:zhlaw_get_articlereturned emptycontentfor single-line PDF extracts
(e.g. VSG § 1): the article parser captured the whole running text into the
title. The parser now derives the marginal-note title and the body separately
socontentis never empty for run-on lines. Offline regression tests added.zhlaw_get_law_metadatano longer resolved on zh.ch — the undated
erlass-<ordnr>.htmllanding URL was removed upstream (returns 404). Live
metadata now uses the stable per-ordinance permalink
http://www.zhlex.zh.ch/Erlass.html?Open&Ordnr=<ordnr>, which redirects to
the current consolidated version onwww.zh.ch.test_live_list_lawsasserted a brittle SR-prefix that does not hold for the
first page (laws are sorted ascending by ordinance number); it now checks the
real invariant (non-empty, ascendingsr_numbers).
Changed
- Egress allow-list (SEC-021 / SEC-004) — added
www.zhlex.zh.chto
EGRESS_ALLOWLISTand introducedHTTP_ALLOWED_HOSTSso that this single
legacy permalink host may be reached over HTTP (it has no HTTPS endpoint).
HTTPS remains mandatory for every other host; the allow-list, SSRF IP-block,
DNS-pinning, and per-hop redirect gate are unchanged. See
docs/network-egress.md. - Documentation consistency — re-synced
README.de.mdwith the English
README.md(Development Phase, network binding, expanded cloud config, design
decision, scaling constraints, MCP protocol version, tool output format,
security rows, updated project tree). UpdatedLICENSEcopyright year to 2026.