Skip to content

Releases: UPinar/contrastapi

v1.34.2 — resilient crypto payment provisioning + dependency/security bumps

18 Jun 14:30

Choose a tag to compare

Crypto billing — resilient payment provisioning

Crypto Pro payments are now provisioned automatically when the received
amount is within a small tolerance of the invoice (covering exchange and
network rounding), instead of requiring an exact-amount settlement.
Genuine underpayments and failed/expired/refunded payments are left
unprovisioned and surfaced to operators. Amounts are validated from the
signature-verified provider notification.

Operational visibility

Operator notifications added for underpaid / failed / expired / refunded
payments and for successful key claims.

Dependencies / security

Tests

2579 passing. Wire-compatible — no API contract, MCP tool (54),
Resource (7) or Prompt (3) changes.

v1.34.0 — Free first call to every tool for new agents

06 Jun 06:52

Choose a tag to compare

What's new

New MCP agents commonly probe every tool once to discover what's available — that initial sweep could previously hit the hourly limit partway through. Now the first call to each distinct tool is free for keyless (Free-tier) callers: a one-time grant per caller, so an agent can complete its discovery pass without being rate-limited. Later calls fall back to the normal hourly limit.

Scope

  • MCP tools/call only — REST endpoints and API-key (Pro) callers are unchanged.
  • Single-credit tools only; composite/orchestration tools keep their cost.
  • One-time per caller.

Notes

  • No contract changes — MCP tools (53), Resources (7), Prompts (3) and all schemas unchanged; existing integrations unaffected.
  • Schema: an internal ledger table created idempotently on startup — no migration step, no downtime.
  • Privacy/abuse: caller identity is hashed and bucketed; abuse-resistant by design.
  • Tests: full suite green with added first-swipe coverage (2510 passing).
  • Rollback: feature is flag-gated.

v1.33.24 — Recon pool hardening + dependency bumps

06 Jun 04:41

Choose a tag to compare

v1.33.24

Reliability

  • recon: reap idle keepalive connections in the SSRF-safe HTTP pool — prevents idle-connection accumulation in the recon / domain-intelligence fetch path.

Dependencies

  • uvicorn 0.48.0 → 0.49.0
  • python-multipart 0.0.30 → 0.0.32
  • phonenumbers 9.0.31 → 9.0.32

Unchanged

  • 53 MCP tools · 7 Resources · 3 Prompts
  • Full test suite green

Follows v1.33.23.

v1.33.22 — Optional outputSchema fields accept null (#42)

01 Jun 15:03

Choose a tag to compare

Fix: lean MCP outputSchema now accepts null for optional fields (#42)

Optional response fields (T | None) were advertised in the lean tools/list
outputSchema by their non-null type only — e.g. verdict as {"type": "object"}.
A tool returning null for such a field (where it isn't computed pre-enrichment)
then failed strict MCP client validation: -32602 ... must be object.

Fix: the null arm is preserved as a flat 2-element type array —
verdict: {"type": ["object", "null"]}, and likewise ["string","null"] /
["array","null"] / ["integer","null"] … for every other optional field.
Resolved centrally in the schema-derivation helper, so it applies to all 53
tools
(223 nullable fields), not just verdict.

  • Stays flat — no $defs/$ref/anyOf — so strict clients (the lean-schema
    consumers) keep validating cleanly.
  • Ambiguous / mixed-type unions stay permissive ({}).
  • Verified on a Draft 2020-12 validator: a null verdict now validates; a
    populated object verdict still does.

Wire-compatible bug fix; no tool/arg changes. MCP surface unchanged
(53 tools · 7 Resources · 3 Prompts). Test suite green.

Reported by @0xawad — thanks for the precise repro.

v1.33.21 — security: urllib3 + click CVE patches

31 May 02:43

Choose a tag to compare

Security

Patches three CVEs in transitive dependencies by pinning the fixed upstream versions. No application behavior change — both packages are transitive-only with no direct imports in app code.

  • urllib3 2.6.3 → 2.7.0
    • CVE-2026-44432 (HIGH): response could be fully decompressed instead of the requested portion on a second read(amt=N) / drain (Brotli).
    • CVE-2026-44431 (MED): sensitive headers forwarded on cross-origin redirects via the low-level ProxyManager path.
  • click 8.3.1 → 8.3.3
    • CVE-2026-7246 (HIGH): command injection in click.edit(). Not reachable from the server (click is transitive via uvicorn/typer; click.edit() is never called).

Compatibility

  • No schema, route, or contract change. MCP tools / Resources / Prompts unchanged (53 / 7 / 3).
  • Pinned explicitly for reproducibility; dependency graph resolves cleanly (pip check / pip-audit green).

Tests

2491 passed (no change — dependency-only bump).

v1.33.20 — recon: graceful crt.sh timeout in domain report

31 May 02:15

Choose a tag to compare

Fix

Domain report no longer fails when crt.sh (Certificate Transparency) upstream times out.

full_domain_report (powering /v1/domain/{domain} and the audit_domain MCP tool) ran its certificate-transparency and subdomain lookups through two closures sharing one crt.sh fetch. When that upstream was slow, the inner timeout was left unhandled — the whole report failed with a 504 even though DNS, WHOIS, SSL, headers and threat data had all resolved successfully.

Now the timeout is caught inside both closures and the report degrades gracefully: it returns 200 with the partial result, and both the certificates and subdomains branches honestly report crtsh_status: "timeout" (instead of one of them masquerading as "ok" with an empty list). Clients get every reachable signal plus a truthful availability flag for the one source that was slow.

Compatibility

  • No schema change. error and crtsh_status fields already existed.
  • Backward compatible. New optional crtsh_error parameter on internal helpers defaults to preserving prior behavior.
  • Status code for the crt.sh-timeout path changes 504 → 200 (partial success).

Tests

2490 → 2491 (added one regression test covering the crt.sh-timeout path on both branches).

MCP tools / Resources / Prompts unchanged (53 / 7 / 3).

v1.33.18 — Correct field types in MCP outputSchema

25 May 16:53

Choose a tag to compare

Fixes #38 — MCP outputSchema field-type accuracy

The lean outputSchema advertised in tools/list previously declared nearly every field as {"type":"object"}, regardless of the field's real value type, because optional fields (T | None) are encoded as anyOf in the source schema and the flattener only inspected a top-level type key. Strict MCP clients (e.g. opencode/dcp) rejected valid tool responses whose values were strings, arrays, numbers, or booleans.

Fix: resolve the real primitive type from the schema's non-null union arm (and one-hop $ref) while keeping the advertised schema flat (no $defs/$ref/anyOf). Fields with no single representable type (mixed-type unions or Any) now emit a permissive schema that validates any value instead of a wrong object type. Hardened against cyclic schema definitions.

Compatibility: wire-compatible — stricter clients now accept responses; lenient clients are unaffected. No tool or argument changes.

  • MCP surface unchanged: 53 tools, 7 Resources, 3 Prompts
  • Adds 13 schema tests (field-type + edge-case + cycle-guard); suite at 2486 passing

Follow-on patch to v1.33.17.

v1.33.14 — Lean outputSchema on tools/list (recover Smithery quality)

22 May 15:57

Choose a tag to compare

Lean (flat) outputSchema reintroduced on tools/list

v1.33.13 stripped outputSchema entirely to fix a Smithery catalog-gateway availability issue (309KB→81KB) — but that dropped Smithery's "Output schemas" quality criterion to 0/53 (−10.37pt).

This release reintroduces a lean, flat outputSchema per tool: the success model's top-level field names + primitive types only (no $defs/$ref/anyOf/prose, ~0.5KB/tool). Each tool re-advertises its output shape and the whole tools/list payload stays at ~104.5KB — well under the gateway buffer.

Changes

  • New _leanify_output_schema() transform in the MCP proxy (wire-only; never touches the FastMCP tool objects). Applied on both the fast-path cache and the lazy-rebuild path.
  • required is filtered to advertised properties (valid JSON Schema).
  • tools/call validation + structuredContent are runtime concerns — unaffected.

Verification

  • tools/list (prod): 53/53 tools carry a flat outputSchema, payload 104.5KB, no $ref on the wire.
  • Tests: 2467 passed (test_mcp.py flips ABSENT→PRESENT+FLAT invariants + per-tool/payload budgets).
  • MCP tools/Resources/Prompts counts unchanged (53/7/3).

v1.33.13 — tools/list payload slim (Smithery availability fix)

22 May 00:31

Choose a tag to compare

Performance / contract — MCP tools/list

Symptom: Smithery Observability reported tools/list 100% Unavailable (transport-level drop, 0% server/client errors) while tools/call worked normally. RPC traffic via Smithery collapsed.

Root cause: the tools/list response had grown to ~309 KB, of which ~73% was outputSchema (FastMCP-derived from Pydantic return models). The catalog gateway could not buffer the oversized body and dropped it.

Fix: stop emitting outputSchema on the wire. It is OPTIONAL per the MCP spec; the call contract (name + description + inputSchema) is fully preserved, and tools/call runtime validation + structuredContent are unaffected. Removed the now-orphaned _slim_output_schema helper (the earlier annotation-only slim kept the 231 KB structure).

Result: tools/list payload 309 KB → 81 KB (~73% reduction), 53 tools, 0 with outputSchema. Production verified.

  • VERSION 1.33.12 → 1.33.13 (cache-prefix invalidation)
  • Tests: 2467 passed (test invariant flipped: outputSchema must be absent + payload < 120 KB on fast-path and cache-None paths)
  • MCP tools/Resources/Prompts counts unchanged (53 / 7 / 3)

v1.33.12 — httpx pool-leak hotfix (S253 reopen)

19 May 23:06

Choose a tag to compare

Hotfix on v1.33.11 — restores /v1/tech, /v1/scan/headers, /v1/domain

A regression of the v1.33.8 _ssrf_http pool-leak class was observed in production
(36-minute PoolTimeout cluster on worker 2805645, 19 May 22:02 UTC) causing
intermittent 504s on three domain-intelligence endpoints. v1.33.10 only suppressed
the "Task exception was never retrieved" log noise; the underlying slot leak
remained. v1.33.12 closes both root causes.

Fixes

  • fetch_live_headers race-and-cancel leak (primary): parallel HTTPS+HTTP
    .get() race cancelled the losing task mid-flight; httpcore never returned the
    pool slot. Refactored to sequential HTTPS-first / HTTP-fallback, mirroring the
    v1.33.7 fetch_live_page pattern. No second task, no cancel, slot always
    returned.

  • full_domain_report orphan-task storm (amplifier): when an early await
    raised (e.g. f_subs TimeoutError on slow crt.sh), the trailing
    create_task handles (f_certs, f_threat, f_whois, f_ab, f_sh,
    f_headers) were never awaited or cancelled — they leaked into the event
    loop and held pool slots. Wrapped the await chain in try/finally that
    cancels + drains any pending task on exit. WAF detection moved inside the
    guarded scope so f_headers is read before cleanup cancels it.

Status-code change for affected paths

Endpoint Pre (v1.33.11) Post (v1.33.12)
/v1/tech/{domain} 504 ~13s (intermittent) 200 ~0.5s
/v1/scan/headers/{domain} 504 ~5s (intermittent) 200 ~0.5s
/v1/domain/{domain} 504 (intermittent under load) 200

No request/response shape change; only the failure mode is removed.

Tests

  • TestFetchLiveHeadersSequential (3) — happy-path call_count=1, HTTP fallback ordering, both-fail error dict.
  • TestFullDomainReportOrphanCleanup (1) — early-timeout regression, asserts no orphan tasks remain after exception unwind.
  • Full suite: 2463 → 2467 passed.

Fold-in

  • CodeQL #111/#112/#113 (Empty-except): added intent comments inside the three
    PRAGMA busy_timeout=5000 reset blocks in app/db.py — the unit-cleanup path
    must never mask the unit's primary error.

Follows

  • v1.33.11 (sigma bulk per-item quota + reflected-echo fix)
  • v1.33.10 (GHSA delta-sync self-pin fix + S253 resilience batch)
  • v1.33.8 (pattern-B streaming-cancel pool-leak hardening — original S253 close)