Skip to content

solar__solar_conditions (and band_outlook) return nulls for SFI/Kp due to SWPC endpoint format changes #3

Description

@KI7MT

Diagnosis

The solar__solar_conditions MCP tool (and dependent solar_band_outlook) consistently returns nulls:

{"sfi":null,"sfi_timestamp":null,"kp":null,"kp_timestamp":null,"noaa_r_scale":"0","noaa_s_scale":"0","noaa_g_scale":"0"}

While other solar tools (solar_alerts, solar_wind, solar_xray, solar_forecast) succeed with live data.

Root Cause (cite-by-grep in client.py)

In src/solar_mcp/client.py:conditions() (called by the tool):

  • SFI fetch: self._get_json(f"{_SWPC}/products/summary/10cm-flux.json")

    • Current response (verified live): [{"flux":128,"time_tag":"..."}] (list of dicts)
    • Code assumption: if isinstance(sfi_data, dict): ... .get("Flux") or .get("flux") (and TimeStamp). Skips for list → sfi=None.
  • Kp fetch: self._get_json(f"{_SWPC}/products/noaa-planetary-k-index.json")

    • Current: list of dicts [{"time_tag":"...","Kp":0.67,...}, ...]
    • Code assumption: if isinstance(latest, list) and len(latest)>=2: float(latest[1]) (legacy list-of-lists). Fails → kp=None.
  • Scales parse partially succeeds but yields raw "0" (instead of "R0" etc.).

No exception raised (graceful degradation), so server.py:solar_conditions returns the partial null dict (not {"error":...}).

_get_json + caching + or {} / or [] hid the shape mismatch.

Other tools use different endpoints (still compatible).

Mocks were also in legacy format.

This matches the observed behavior in fleet (e.g., Grok solar brief calls).

Evidence

  • Direct curl + python inspection of live SWPC endpoints (2026-06-15).
  • solar__get_version_info: solar-mcp 0.2.0 / noaa-swpc-v1.
  • Live repro via MCP tool calls + fallback web/NOAA pages.
  • Code review of client.py:125-187 (and band_outlook:411-416 which bails on nulls).

The endpoints were updated post-0.2.0 release (code written ~May 2026 for older shapes).

Solution (implemented on branch)

  • Made conditions() parsing robust: handles current list-of-dicts + legacy formats for both SFI and Kp.
  • Normalize scales "0""R0"/"S0"/"G0" for consistency with tests/docs.
  • Updated _MOCK_* data to current shapes (unit tests now exercise new paths).
  • Added to Unreleased in CHANGELOG.md.
  • Verified: live client.conditions() now returns real SFI=128, Kp=0.67 (latest), normalized scales, band_outlook.
  • (Editable install in workspace picks up src via .pth; MCP calls succeed.)

Branch: fix/solar-conditions-parsing
PR will follow.

Recommended follow-ups

  • Run full L3 live tests: pytest tests/test_live.py --live
  • Consider defensive {"error": ...} if parse still fails.
  • Bump __spec_version__ on next release if more drifts.
  • Monitor these two endpoints (NOAA JSON shapes not guaranteed stable).
  • Fleet: re-deploy solar-mcp 0.2.1+ across nodes (M3, 9975WX, etc.) once tagged.

This restores solar_conditions for the observability plane / HF propagation use (cross-ref ionis-mcp, observability-plane.md, etc.).

Fixes the nulls seen in recent solar brief queries.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions