Skip to content

v0.2.0 — First production-ready release

Choose a tag to compare

@malkreide malkreide released this 29 May 13:05
b39498f

openlex-mcp v0.2.0

First production-ready release. Resolves all 31 findings from the initial
MCP best-practice audit plus all 4 findings from the follow-up re-audit
(2026-05-29): 40/44 checks pass, 0 fail, production_ready: true.

⚠️ Breaking Changes

  • Tool output contract (SDK-002): all 8 tools now return typed, structured
    response envelopes (source / provenance / result_type / count /
    message / typed results) instead of pre-formatted Markdown strings.
    FastMCP now emits an output schema + structuredContent for every tool.
    Clients parsing the old Markdown text output must migrate to the envelope.

✨ Added

  • Structured logging (OBS-003): structlog JSON to stderr with per-call
    bound context (tool + correlation_id).
  • Hardened egress (SEC-004/005/021): HTTPS-only, code-layer egress
    allow-list, SSRF IP-blocking (incl. 169.254.169.254), DNS-pinning, manual
    redirect re-validation.
  • Lifespan-scoped shared httpx.AsyncClient (SDK-001).
  • CORS for browser clients (SDK-004): exposes Mcp-Session-Id, no wildcard.
  • Dockerfile + compose.yml (SEC-007/SCALE-004/006): non-root multi-stage
    image, HEALTHCHECK, resource limits.
  • pydantic-settings Settings + MCP_TRANSPORT (ARCH-004/SCALE-001).
  • openlex__ tool namespace + tool-hash snapshot (SEC-022).
  • MCP_PROTOCOL_VERSION = 2025-11-25 pin + Dependabot (ARCH-012).
  • Strict input validation (SEC-018): strict=True on all 8 models.
  • Context injection in zhlaw_update_cache (SDK-003): progress + info/warning.
  • Live tests + nightly workflow (OPS-001): tests/test_live.py (8 tests,
    one per tool) + .github/workflows/live.yml.
  • Structured tool docstrings (ARCH-002): <use_case> / <important_notes>
    / <example> tags on all 8 tools.

🔧 Changed

  • Error handling (OBS-001/002): execution errors surfaced as masked
    isError results; internals logged to stderr only.
  • HTTP binding (SEC-016): defaults to 127.0.0.1; NeighborJack warning on
    public binding outside containers.

🐛 Fixed

  • User-Agent no longer contains a non-ASCII character (ZürichZuerich).

📚 Docs

  • ROADMAP.md (Phase 1 → 2 gates, accepted-risk table), docs/secret-management.md,
    docs/network-egress.md, bilingual README updates.

🧪 Test Suite

  • 89 unit tests (Python 3.11 / 3.12 / 3.13) + 8 live tests (nightly).

🔒 Audit

  • 40 pass · 0 fail · 4 partial (2 accepted-risk: SCALE-002/003 — Phase-2 gates).
  • production_ready: true, 0 blocking findings.

Full changelog: v0.1.0...v0.2.0