Skip to content

v0.3.4

Latest

Choose a tag to compare

@malkreide malkreide released this 31 Jul 20:16
f2d5556

[0.3.4] — 2026-07-31

Geaendert

  • Der User-Agent traegt jetzt eine Version. Bisher sendete der Server
    schlicht sbb-opendata-mcp — erkennbar, aber ohne Angabe, welcher Stand da
    anfragt. Damit liess sich ein Problem keiner Release zuordnen. Neu
    traegt den HTTP-Client sbb-opendata-mcp/<version> (+github.com/malkreide/sbb-opendata-mcp).

    Die Version stammt aus importlib.metadata und kann nicht getrennt vom
    Paket driften.

Fixed

  • Der Container band Loopback und war von aussen nicht erreichbar. Das
    Dockerfile setzt MCP_HOST=0.0.0.0 und exponiert 8000, aber der Code las
    MCP_HOST nicht mehr: die Migration auf mcp 2.x entfernte
    host=os.environ.get("MCP_HOST", "127.0.0.1") aus dem Konstruktor und ersetzte
    es durch ein hart verdrahtetes bind_host = "127.0.0.1". Der publizierte Port
    erreichte damit nichts. MCP_HOST wird wieder gelesen, zusätzlich MCP_PORT
    und ein --host-Flag analog zum bestehenden --port.

  • Die Host/Origin-Allow-List war toter Code — und von zwei Tests gedeckt
    (SEC-005).
    Dieselbe Migration entfernte
    transport_security=_transport_security() aus dem Konstruktor, ohne es als
    run()-Kwarg wieder anzuhängen. _transport_security() blieb stehen, seine
    Unit-Tests blieben grün, und der Server prüfte den Host-Header nie. Testdeckung
    für einen nicht verdrahteten Schutz ist schlechter als keine, weil sie als
    Zusicherung gelesen wird.

    Die Allow-List reist jetzt in run(). Der Builder liefert bewusst None,
    wenn keine Allow-List ableitbar ist — Nicht-Loopback-Bind ohne
    MCP_ALLOWED_HOSTS —, weil der Loopback-Default dort jede echte Anfrage mit
    HTTP 421 abweisen würde; der Aufrufer warnt stattdessen. Bestehende
    Deployments verhalten sich damit unverändert.

  • Der Einstiegspunkt liegt jetzt in main(). Er stand inline im
    __main__-Block, weshalb kein Test die Transport-Verdrahtung sehen konnte —
    genau das liess die beiden Regressionen oben durchrutschen. Neue Tests prüfen
    die run()-Aufrufe selbst statt nur die Bauteile: dass host, port und
    transport_security ankommen, dass stdio keine davon bekommt, und dass
    --host die Umgebung überschreibt. Ein weiterer Test nagelt das Paar
    „Dockerfile setzt MCP_HOST" / „Code liest es" zusammen fest.

    Nachgemessen an der echten ASGI-App in drei Szenarien: Container ohne
    Allow-List lässt alles durch und warnt; Container mit MCP_ALLOWED_HOSTS
    liefert 200 für den richtigen Hostnamen, 421 für evil.example.com und 421
    für den richtigen Hostnamen auf falschem Port
    — nur der letzte Fall
    unterscheidet eine portgenaue Allow-List von einer, die alles erlaubt.