Skip to content

Releases: malkreide/sbb-opendata-mcp

v0.3.4

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.

Release 0.3.0

Choose a tag to compare

@malkreide malkreide released this 06 Jun 18:48
462ea92

sbb-opendata-mcp v0.3.0

Erstveröffentlichung auf PyPI 🎉 — installierbar via pip install sbb-opendata-mcp und uvx sbb-opendata-mcp.

Added

  • PyPI-Publishing via GitHub Actions Trusted Publishing (OIDC, tokenlos).
  • CI: Test + Lint über Python 3.11/3.12/3.13.
  • Docker: Multi-Stage Non-Root Dockerfile, docker-compose mit Ressourcenlimits.
  • Dokumentation: CONTRIBUTING, SECURITY, EXAMPLES, RELEASING, Demo-Asset.

Changed

  • README (EN/DE) auf die Portfolio-Struktur umgestellt; Versionsangleich auf 0.3.0.
  • Lizenz-Metadaten auf PEP-639-SPDX umgestellt (saubere twine check-Validierung).

Keine Code-/Verhaltensänderung am Server – alle 60 Tests grün.

Release 0.2.0 — full MCP audit remediation (10/10 findings, PRs #2–#7)

Choose a tag to compare

@malkreide malkreide released this 05 Jun 04:03
0b780d6

sbb-opendata-mcp v0.2.0 — Audit-Remediation & Hardening

Dieses Release schliesst die vollständige Remediation eines MCP-Sicherheits- und
Qualitäts-Audits ab (durchgeführt mit der mcp-audit-skill).
Alle 10 Findings (2 High · 4 Medium · 4 Low) wurden behoben — über die PRs #2#7.
Es gibt keine Breaking Changes für bestehende MCP-Clients: der menschenlesbare
Markdown-Output aller Tools bleibt unverändert.

🔒 Security

  • ODSQL-Injection geschlossen (F-SEC-01): year/canton werden per Regex validiert,
    alle in die where-Klausel interpolierten Werte (inkl. zuvor ungeschützter
    operator/phase/traffic_type) laufen über ein zentrales Escaping.
  • Streamable-HTTP-Transport gehärtet (F-SEC-02): DNS-Rebinding-/Origin-Schutz aktiv;
    Bind-Host und Allowlists via MCP_HOST / MCP_ALLOWED_HOSTS / MCP_ALLOWED_ORIGINS.
  • Keine Error-Leaks mehr (F-SEC-03): Upstream-Bodies/Exception-Details landen nur noch
    im Server-Log, der Client erhält bereinigte Meldungen.
  • Supply Chain (F-SEC-04): Abhängigkeiten mit Major-Caps gepinnt + reproduzierbarer uv.lock.

📈 Observability

  • Strukturiertes Logging (F-OBS-01) auf stderr (stdout bleibt dem stdio-JSON-RPC-Kanal
    vorbehalten), konfigurierbar über LOG_LEVEL und LOG_FORMAT (text/json).

⚡ Performance

  • Connection-Pooling + Nebenläufigkeit (F-SCALE-01): gemeinsamer httpx.AsyncClient
    mit Keep-Alive; compare_stations ruft die Stationen parallel ab (vorher 2×N sequentiell).

🧩 API & DX

  • MCP structuredContent auf allen Tools (F-SDK-01) — zusätzlich zum Markdown-Text,
    additiv und nicht-breaking.
  • response_format jetzt auch für compare_stations (F-ARCH-01).
  • Robuste Zahlenformatierung der Nutzfläche (F-SEC-05).
  • pip install -e ".[dev]" funktioniert (dev-Extra), pytest-Marker live registriert (F-OPS-01).

✅ Qualität

  • Testsuite 34 → 60 Tests (alle grün), ruff check sauber.
  • Audit-Evidenz unter audits/2026-06-04-sbb-opendata-mcp/ (alle Findings als closed dokumentiert).

📦 Installation

uvx sbb-opendata-mcp        # oder: pip install sbb-opendata-mcp