Metadata-Version: 2.4
Name: heliospice
Version: 0.2.0
Summary: Spacecraft ephemeris made easy — auto-managed SPICE kernels for heliophysics missions
Project-URL: Homepage, https://github.com/huangzesen/heliospice
Project-URL: Repository, https://github.com/huangzesen/heliospice
Project-URL: Issues, https://github.com/huangzesen/heliospice/issues
Author: Zesen Huang
License-Expression: MIT
License-File: LICENSE
Keywords: ephemeris,heliophysics,naif,solar,spacecraft,spice,trajectory
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: requests>=2.28
Requires-Dist: spiceypy>=6.0.0
Provides-Extra: dev
Requires-Dist: beautifulsoup4>=4.12; extra == 'dev'
Requires-Dist: mcp>=1.26.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: mcp>=1.26.0; extra == 'mcp'
Description-Content-Type: text/markdown

# heliospice

Spacecraft ephemeris made easy — auto-managed SPICE kernels for heliophysics missions.

**heliospice** wraps [SpiceyPy](https://github.com/AndrewAnnex/SpiceyPy) with automatic kernel download, caching, and loading. Ask for a spacecraft position and heliospice handles the rest: downloading the right NAIF kernels, loading them in the correct order, and returning results as Python dicts or pandas DataFrames.

## Installation

```bash
pip install heliospice
```

For MCP server support (Claude Desktop, Claude Code, Cursor, etc.):

```bash
pip install heliospice[mcp]
```

## Quick Start

```python
from heliospice import get_position, get_trajectory

# Where is Parker Solar Probe right now?
pos = get_position("PSP", observer="SUN", time="2024-01-15", frame="ECLIPJ2000")
print(f"PSP is {pos['r_au']:.3f} AU from the Sun")

# Get a month of trajectory data as a DataFrame
df = get_trajectory(
    "PSP", observer="SUN",
    time_start="2024-01-01", time_end="2024-01-31",
    step="1h", frame="ECLIPJ2000",
)
print(df[["r_au"]].describe())
```

Kernels are automatically downloaded from [NAIF](https://naif.jpl.nasa.gov/) on first use and cached in `~/.heliospice/kernels/`.

## Supported Missions

### With SPICE Kernels (auto-downloaded)
- **PSP** (Parker Solar Probe) — 2018-2030
- **Solar Orbiter** (SOLO) — 2020-2030
- **STEREO-A** — 2017-2031
- **Juno** — 2011-present (updated regularly)
- **Voyager 1/2** — 1981-2100 / 1989-2100
- **New Horizons** — 2019-2030

### NAIF IDs Only (no auto-download yet)
- **ACE**, **Wind**, **DSCOVR**, **MMS** (1-4) — no public SPK kernels exist
- **Cassini**, **MAVEN** — require multi-segment kernel loading (planned)
- **Galileo**, **Pioneer 10/11**, **Ulysses**, **MESSENGER**, **STEREO-B**

### Natural Bodies
Sun, Earth, Moon, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto

## API Reference

### Position & Trajectory

```python
from heliospice import get_position, get_trajectory, get_state

# Single position
pos = get_position("ACE", observer="EARTH", time="2024-06-01", frame="GSE")

# Full state (position + velocity)
state = get_state("PSP", observer="SUN", time="2024-01-15", frame="ECLIPJ2000")

# Trajectory timeseries (returns pandas DataFrame)
df = get_trajectory(
    "Cassini", observer="SATURN",
    time_start="2010-01-01", time_end="2010-12-31",
    step="6h", frame="ECLIPJ2000",
    include_velocity=True,
)
```

### Coordinate Transforms

```python
from heliospice import transform_vector, list_available_frames

# J2000 to Ecliptic
v_ecl = transform_vector([1.0, 0.0, 0.0], "2024-01-15", "J2000", "ECLIPJ2000")

# RTN transform (requires spacecraft)
v_rtn = transform_vector(
    [5.0, -3.0, 1.0], "2024-01-15",
    from_frame="ECLIPJ2000", to_frame="RTN",
    spacecraft="PSP",
)

# List all frames
print(list_available_frames())
```

### Mission Registry

```python
from heliospice import resolve_mission, list_supported_missions

# Resolve name aliases
naif_id, key = resolve_mission("Parker Solar Probe")  # -> (-96, "PSP")

# List all spacecraft
missions = list_supported_missions()
```

### Kernel Management

```python
from heliospice import get_kernel_manager

km = get_kernel_manager()
km.ensure_mission_kernels("PSP")  # Download + load
print(km.get_cache_info())        # Cache stats
km.unload_all()                    # Free memory
```

## Configuration

| Method | Description |
|--------|-------------|
| `HELIOSPICE_KERNEL_DIR` env var | Override kernel cache directory |
| `KernelManager(kernel_dir=...)` | Per-instance override |
| Default | `~/.heliospice/kernels/` |

## MCP Server

heliospice includes an [MCP](https://modelcontextprotocol.io/) server for LLM tool use:

```bash
# Run directly
heliospice-mcp

# Or via Python
python -m heliospice.server
```

### Claude Desktop Configuration

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "heliospice": {
      "command": "heliospice-mcp"
    }
  }
}
```

### Available MCP Tools

| Tool | Description |
|------|-------------|
| `get_spacecraft_position` | Position at a single time |
| `get_spacecraft_trajectory` | Position timeseries |
| `get_spacecraft_velocity` | Velocity timeseries |
| `compute_distance` | Distance between two bodies |
| `transform_coordinates` | Coordinate frame transform |
| `list_spice_missions` | Supported missions |
| `list_coordinate_frames` | Available frames with descriptions |
| `manage_kernels` | Kernel cache management |

## License

MIT

<!-- mcp-name: io.github.huangzesen/heliospice -->
