@rmp/propagation-mcp
v0.1.0
Published
MCP server exposing HF band-condition and space-weather tools backed by NOAA/SWPC's public feeds
Readme
propagation-mcp
An MCP server exposing HF band-condition and space-weather tools backed by NOAA/SWPC's public JSON feeds. Runs over stdio, so any MCP-compatible client (Claude Desktop, Claude Code, etc.) can launch it as a subprocess.
Installation
npx @rmp/propagation-mcpTools
get_band_conditions
No input. Fetches the current 10.7cm Solar Flux Index (SFI), planetary K-index, planetary A-index, and NOAA's current G-scale reading, then runs them through the classic ham-radio SFI/K/A heuristic to produce a per-band (160m/80m/40m/20m/17m/15m/12m/10m) good/fair/poor call with plain-English notes, plus an overall status. Day/night bias in the per-band notes is based on the server's local time (the tool takes no location input).
Example use: "Are the bands open right now?" / "What's a good band for HF right now?"
Returns text like:
Good conditions overall (SFI 145, K 2, A 8, daytime) — high bands should be open, low bands usable.
Per-band:
- 160m: FAIR — 160m is D-layer absorbed during the day...
- ...
- 10m: GOOD — SFI 145 supports good daylight openings on 10m.
Raw inputs: SFI=145 sfu (as of 2026-08-15T20:00:00 UTC), K=2 (as of 2026-08-16T09:00:00 UTC), A=8, NOAA G-scale=0 (none).plus a structuredContent object with the same data machine-readable.
Deliberately stops at 10m — no 6m. 6m (50MHz) is mostly opened by mechanisms this tool has no data for: sporadic E (jet-stream/season driven, essentially uncorrelated with SFI), meteor scatter, TEP, and aurora (which tracks K-index in the opposite direction from HF — high K opens auroral backscatter rather than blacking the band out). True F2-layer openings on 6m do exist but are rare even at high SFI. Extending the existing SFI/K/A heuristic with just a higher SFI threshold for 6m would produce a confidently-wrong answer on the far more common case of Es being wide open while SFI/K say "poor" — worse than not answering at all. A correct 6m tool would need its own data source (e.g. sporadic-E cluster-spot aggregation or foEs ionosonde data, neither of which NOAA/SWPC's feeds used here provide), so it's left out rather than faked.
get_solar_indices
No input. Returns the latest raw SFI, Kp, and A-index values with their NOAA observation timestamps (UTC). Use this when you want the raw numbers rather than an interpreted band-by-band call.
get_kindex_forecast
No input. Returns NOAA's 3-day-ahead planetary K-index forecast table (one row per 3-hour period), each with UTC time, predicted Kp, and NOAA G-scale (when a storm threshold is predicted to be reached).
get_space_weather_alerts
Optional input { limit?: number } (default 5). Returns the N most recent
active NOAA/SWPC alerts/watches/warnings (geomagnetic K-index warnings, radio
blackout alerts, proton flux alerts, etc.), most-recent-first, each with its
product code, UTC issue time, and a short plain-English extract of the
bulletin (not the full raw text dump).
get_solar_wind
No input. Returns the current real-time solar wind reading: interplanetary magnetic field strength (Bt) and its north-south GSM component (Bz — a sustained southward/negative Bz is what actually couples energy into the magnetosphere and tends to precede a Kp rise by 30-60 minutes), plus proton speed, density, and temperature. Bt/Bz come from NOAA's pre-resolved "current" summary endpoints; density/temperature come from the fuller multi-spacecraft feed, filtered to whichever source NOAA currently flags as authoritative (that feed carries several spacecraft — ACE, SOLAR1, IMAP as of writing — at each timestamp, sorted newest-first, so picking the right row takes a touch more care than the other endpoints here).
get_xray_flux
No input. Returns the latest GOES X-ray flux in both channels (long,
0.1-0.8nm; short, 0.05-0.4nm) plus NOAA's own current flare classification
(e.g. "C1.5", standard A/B/C/M/X logarithmic scale) and the most recent
classified flare event's begin/peak/end times and classes. The flare class
is passed through verbatim from NOAA rather than re-derived from raw flux
here — NOAA already computes and publishes it, so re-implementing the
threshold table ourselves would just be a second place for that logic to
drift out of sync with theirs.
Development
npm install
npm run build
npm testTests use Node's built-in test runner (node:test) and stub globalThis.fetch
with real sample NOAA payloads — no network access required.
Using with Claude Desktop / Claude Code
The published package needs no clone or build — point your client straight at it:
{
"mcpServers": {
"propagation": {
"command": "npx",
"args": ["@rmp/propagation-mcp"]
}
}
}To run from a local checkout instead, build first (npm run build) and point
at the built entry point:
{
"mcpServers": {
"propagation": {
"command": "node",
"args": ["/Users/rmp/dev/mcp/propagation-mcp/dist/index.js"]
}
}
}Adjust the path to match where you've cloned this repo. For Claude Desktop
this goes in claude_desktop_config.json; for Claude Code, in your MCP
server configuration (e.g. via claude mcp add or the project's
.mcp.json).
Standalone binaries (no Node, no node_modules)
For deploying to a Raspberry Pi or any other box you don't want carrying a Node install and this whole source tree, the server is also shipped as a single self-contained executable per architecture — the Bun runtime is embedded in the binary, so nothing else needs to be installed on the target.
Every tagged release attaches them, alongside a SHA256SUMS.txt:
gh release download v0.1.0 --pattern 'propagation-mcp-linux-arm64' --pattern 'SHA256SUMS.txt'
sha256sum --check --ignore-missing SHA256SUMS.txt
chmod +x propagation-mcp-linux-arm64To build them yourself, build:standalone compiles straight from
src/index.ts with Bun — one x86-64 machine cross-compiles
all three:
curl -fsSL https://bun.sh/install | bash # one-time, only needed on the build machine
npm run build:standaloneEither way you get:
propagation-mcp-linux-amd64— most Linux boxes / generic x86-64 servers (~91MB)propagation-mcp-linux-arm64— Raspberry Pi 4/5 (64-bit Raspberry Pi OS) and other arm64/aarch64 Linux (~90MB)propagation-mcp-darwin-arm64— Apple Silicon macOS (~62MB)
The size is the embedded Bun runtime, not this package's own code. The macOS
binary is unsigned and unnotarized, so a downloaded copy needs
xattr -d com.apple.quarantine propagation-mcp-darwin-arm64 before Gatekeeper
will run it. Each binary runs with no arguments needed — copy it to the target
and point your MCP client's command straight at it instead of
node .../dist/index.js:
{
"mcpServers": {
"propagation": {
"command": "/home/pi/propagation-mcp-linux-arm64"
}
}
}Both architectures were verified by actually running the compiled binary
under Docker (--platform linux/amd64 / --platform linux/arm64) and
exercising a real MCP handshake, tools/list, and a live get_solar_indices
call against the real NOAA API — not just checking that the binary exists.
