AI agent for heliophysics and space plasma data analysis.
Ask questions in natural language — HelioAI finds the right parameter across 70+ missions, downloads it, runs the analysis, and produces reproducible plots and notebooks.
You: "IP shock in WIND data, January 2005 — compute θ_Bn"
HelioAI: → resolves param IDs for B, Vp, Np across 83k speasy products
→ downloads the time series via speasy (AMDA / CDAWeb / CSA)
→ runs shock detection + coplanarity theorem in a sandboxed Python env
→ returns a plot, the θ_Bn value, and a reproducible .ipynb notebook
No API key required for data access. No manual parameter hunting.
- Hybrid RAG — semantic (MiniLM) + lexical (BM25) search over 83k parameters, fused by Reciprocal Rank Fusion. Finds both vague descriptions and exact codes (
BGSEc,FGM,igrf_8sec_gse). - Event catalogs & timetables — access 217 curated AMDA catalogs (ICMEs, bow-shock crossings, reconnection events, substorms, …). Download a parameter across every event in one call — the foundation for superposed epoch analysis and statistical surveys.
- PlasmaPy tools — plasma β, gyrofrequency, Debye length, Alfvén speed, inertial length, power spectrum — ready-made for the agent.
- Sandboxed Python — the agent writes and runs analysis code under bubblewrap isolation on Linux (see SECURITY.md). All scripts are saved for reproducibility.
- 6 specialised skills —
parameter_hunter,data_analyst,plasma_physicist,librarian,plotting,helioai_helper— loaded as markdown, zero coupling to the agent loop. - Derived recipes — 10 reusable scientific scripts, each with a cited reference: θ_Bn, Walén test, MVAB, Rankine-Hugoniot jump conditions, two-spacecraft shock timing, pressure balance, pitch angle distribution, superposed epoch, SEP onset (Poisson-CUSUM), Parker spiral connectivity.
- Literature search —
find_papersqueries NASA ADS for papers relevant to an event or parameter; a dedicatedlibrariansub-agent handles multi-round literature searches without derailing the main analysis. - Fill value masking —
clean()helper in the sandbox automatically masks CDF fill values (|x| ≥ 1e30,±inf) before any plot or analysis. - Data quality checks — every
get_timeseriesdownload is scanned (deterministically, no LLM) for missing/fill values, data gaps, and 5σ outliers; the agent flags them only when they matter, so you know what you're working with before analysis. - Plan preview — for a multi-step request the agent first lays out a short structured plan (the steps and the tool/method each will use), then executes — transparent, no black box.
- Standalone notebook export — any session exports as a self-contained
.ipynb:load_data()calls are rewritten to directspz.get_data(...), sandbox-only helpers are stripped, and a Methods & data acknowledgements cell lists the recipes and references used — every cell re-runs in a plain Jupyter kernel. - Multiple interfaces — interactive CLI, Jupyter magic, Web UI (FastAPI + SSE + activity dock), MCP server (Claude Desktop /
claudeCLI). - User profile — inject your preferred missions, domain, and plot style once; the agent adapts to you.
- Heliophysics scope guardrail — the agent stays on-topic; a dev token unlocks unrestricted mode for development.
pip install helioai-agentOr from source with uv:
git clone https://github.com/erdoganfurkan/HelioAI.git
cd HelioAI
uv syncFirst run — build the parameter index (one-time, ~10 min, 83k products):
helioai indexThis downloads the speasy catalogue and indexes it into a local ChromaDB. It lands in
<repo>/data/ when running from a clone, and in ~/.local/share/helioai/ when installed
from PyPI — override either with HELIOAI_DATA_DIR.
Copy .env.example to .env and set at least one LLM provider key:
# LLM provider (groq | gemini | azure | opencode | ollama)
HELIOAI_LLM_PROVIDER=groq
GROQ_API_KEY=your_key_here
GEMINI_API_KEY=your_key_here
# Azure OpenAI (if using azure)
AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_ENDPOINT=...
AZURE_OPENAI_DEPLOYMENT=gpt-4o
# OpenCode Zen (if using opencode) — however you reach it (Go plan, BYOK), no default model
OPENCODE_API_KEY=...
HELIOAI_OPENCODE_MODEL=...
# Ollama (if using ollama — no API key needed)
HELIOAI_OLLAMA_URL=http://localhost:11434
HELIOAI_OLLAMA_MODEL=qwen2.5:14b-instruct| Provider | Model | Notes |
|---|---|---|
groq |
llama-3.3-70b-versatile |
Free tier, fast — recommended to start |
gemini |
gemini-2.5-flash |
Better reasoning, generous free quota |
azure |
configurable | Enterprise deployments |
opencode |
configurable | OpenCode's Zen gateway, OpenAI-compatible |
ollama |
qwen2.5:14b-instruct |
Fully local, no API key |
Any other OpenAI-compatible endpoint works too — providers are a base_url entry in
helioai/core/llm/factory.py, not a class.
helioaihelioai> solar wind density from ACE in January 2005
helioai> compare MMS and Cluster magnetic field during 2017-07-11 reconnection event
helioai> compute plasma beta in the magnetosheath — B=20nT, n=20cm-3, T=200eV
helioai> show me the IMF Bz for all ICMEs in the Richardson & Cane catalog between 2003 and 2005
helioai> superposed epoch analysis of MMS bow-shock crossings — proton density, 2017
One-shot mode:
helioai "IP shock detection in WIND/MFI data, 2005-01-16 to 2005-01-17"%load_ext helioai.interfaces.jupyter_magic%%helioai
Download Bz from ACE for the 2003 Halloween storm and plot the storm sudden commencement.Figures render inline. Export the session as a notebook:
%helioai_exporthelioai serve --web
# → http://localhost:7890Three-panel layout: conversation · artifact viewer (plots, parameter cards) · code panel (generated scripts).
Add to your claude_desktop_config.json:
{
"mcpServers": {
"helioai": {
"command": "helioai-mcp"
}
}
}Or run the HTTP MCP server:
helioai-mcp --http --port 8080docker compose -f docker/docker-compose.yml up -d
# → http://localhost:7890Mount ./data for persistent index and sessions. Set your LLM keys in .env.
| Provider | Missions (examples) | Parameters |
|---|---|---|
| AMDA (CDPP) | Cluster, MMS, Solar Orbiter, WIND, ACE, Cassini, Helios, STEREO | ~12k |
| CDAWeb (NASA) | MMS, THEMIS, Van Allen Probes, Parker Solar Probe, Ulysses, Voyager | ~68k |
| CSA (ESA) | Cluster, Double Star, Solar Orbiter, Mars Express | ~1.9k |
In addition, 217 AMDA event catalogs and timetables are accessible as first-class tools: ICMEs (Richardson & Cane — 341 events, ICME multi-catalog — 2003 events), bow-shock crossings (MMS 2797, THEMIS ~60k), magnetic reconnection EDR events (72), substorm onsets (2437), flux transfer events, MAVEN shock crossings (3837), and monthly MMS burst-mode timetables (2015–present).
Full parameter catalogue via list_missions() or helioai "what missions are available".
Full catalog catalogue via list_catalogs() or helioai "what event catalogs are available".
| Tool | Description |
|---|---|
search_parameters |
Hybrid RAG search — single query or batch queries=[...] |
get_timeseries |
Download a parameter via speasy (returns cadence, mission, components) |
list_missions |
Live catalogue of providers and missions |
| Tool | Description |
|---|---|
list_catalogs |
Browse 217 AMDA catalogs/timetables — filter by type and region keyword |
get_catalog |
Download and inspect a catalog: event count, columns, time-filtered sample |
get_events_timeseries |
Download a parameter across every event in a catalog (one speasy call) — core tool for superposed epoch analysis |
| Tool | Description |
|---|---|
find_papers |
Search NASA ADS for papers relevant to an event, parameter, or method |
| Tool | Description |
|---|---|
run_python |
Sandboxed Python — speasy + plasmapy + numpy + matplotlib available |
plasma_beta |
β = nkT / (B²/2μ₀) |
gyrofrequency |
Ion/electron gyrofrequency for a given B |
debye_length |
Debye screening length |
alfven_speed |
Alfvén speed V_A = B / √(μ₀ρ) |
inertial_length |
Ion/electron inertial length |
power_spectrum |
Welch PSD on a time series |
list_recipes |
Catalogue of scientific Python recipes |
load_recipe |
Load a recipe source + reference (θ_Bn, Walén, MVAB, Rankine-Hugoniot, pressure balance, pitch angle dist, superposed epoch) |
task |
Delegate to a specialised sub-agent |
| Role | Purpose | Max turns |
|---|---|---|
parameter_hunter |
Resolve vague descriptions → speasy parameter IDs | 4 |
data_analyst |
Download, analyse, plot, multi-mission, event detection | 8 |
plasma_physicist |
PlasmaPy calculations, sanity checks by region | 4 |
librarian |
NASA ADS literature search, multi-round funnel | 4 |
helioai/
├── config.py env vars, provider settings, RAG config
├── core/
│ ├── agent_loop.py async streaming agent (stream_chat)
│ ├── sub_agents.py specialised sub-agents (parameter_hunter, …)
│ ├── tool_exec.py shared tool execution logic
│ ├── session.py SQLite conversation history
│ ├── skills_loader.py markdown skill loader
│ ├── skills/ 6 × SKILL.md
│ └── llm/ groq · gemini · azure · ollama + factory
├── tools/
│ ├── rag.py hybrid BM25+dense RAG (RRF fusion)
│ ├── speasy_tools.py search_parameters, get_timeseries, list_missions
│ ├── plasmapy_tools.py 6 plasma physics functions
│ ├── sandbox.py sandboxed Python execution
│ └── recipes.py scientific recipe loader
├── interfaces/
│ ├── cli.py readline CLI
│ ├── jupyter_magic.py IPython magic
│ └── web/ FastAPI + SSE + vanilla JS UI
├── mcp_server.py MCP stdio + HTTP streamable
├── export.py session → reproducible .ipynb
├── indexer.py speasy catalogue → ChromaDB
└── docker/ Dockerfile + docker-compose.yml
uv sync --extra dev
.venv/bin/python -m pytest # 797 tests, 80% coverage (no exclusions)
.venv/bin/python -m ruff check . # lint
.venv/bin/python -m ruff format . # formatPre-commit hooks (ruff + trailing-whitespace):
pre-commit install- CI/CD — GitHub Actions (lint + test matrix Python 3.12/3.13/3.14)
- Docker —
helioai serve --webin a container (docker/) - PyPI release —
pip install helioai-agent - JOSS paper
MIT — see LICENSE.