Skip to content

v0.2.0 — Production hardening (audit remediation)

Choose a tag to compare

@malkreide malkreide released this 01 Jun 16:30
af2bb44

v0.2.0 — Production hardening (audit remediation)

This release closes the security/production-readiness audit: from
11 pass / 26 partial / 7 fail at baseline to 39 pass / 5 partial / 0 fail
across the 44 applicable checks — all failed checks resolved, 0 blocking findings.

Highlights

Cloud transport, for real

  • Env-driven transport selection (MCP_TRANSPORT, MCP_HOST, MCP_PORT); the
    advertised Streamable-HTTP transport is now actually implemented (default stays
    stdio). CORS allow-list (MCP_CORS_ORIGINS) exposing Mcp-Session-Id.
  • Multi-stage Dockerfile (non-root UID 10001, HEALTHCHECK), render.yaml
    blueprint, /healthz probe, $PORT fallback.

Security (SSRF / egress / transport)

  • Egress allow-list guard (ALLOWED_HOSTS + _assert_safe_url): HTTPS-only,
    host allow-list, resolved-IP blocklist before any outbound request.
  • DNS-pinned HTTP transport (_PinnedNetworkBackend): host resolved exactly
    once, IP validated and the TCP connection pinned to it, TLS SNI/cert still
    verified against the hostname — eliminates the resolve/connect TOCTOU (SEC-005).
  • Pydantic strict=True input models; errors surface as sanitized MCP isError
    results (no raw exception text to the model). docs/SECURITY.md threat model.

MCP / SDK

  • Typed structured tool output (SDK-002): all 6 tools declare Pydantic output
    schemas and return a hybrid CallToolResult — curated Markdown/JSON in
    content plus validated structuredContent. Machine-readable, no UX loss.
  • ctx: Context injection in every tool; tool annotations
    (readOnlyHint/openWorldHint); protocolVersion constant + policy.

Observability

  • Structured JSON logging (structlog) to stderr (stdout reserved for the
    stdio JSON-RPC stream); per-call bound context (tool, correlation_id).
  • OpenTelemetry on by default (OBS-006): MCP_OTEL_ENABLED defaults on;
    silent no-op without the [otel] extra. TracerProvider + OTLP + Starlette/httpx
    auto-instrumentation. MCP_OTEL_ENABLED=0 to disable.

Ops / supply chain

  • Pooled lifespan-managed httpx.AsyncClient; unit/live test split;
    scripts/snapshot_tool_hashes.py records SHA-256 of tool definitions (SEC-022);
    deploy/haproxy.cfg sticky-session reference for horizontal scaling.

Remaining (non-blocking, by design)

SEC-009 (no-auth, accepted-risk), SCALE-002/003 (multi-instance, deferred),
SEC-014/015 (enterprise gateway, accepted-risk). See
docs/audit/2026-06-01-reaudit/.

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