Skip to main content
Glama
darshan0548

satellite-conjunction-mcp

by darshan0548
README.md
# Satellite Conjunction MCP Server

An MCP (Model Context Protocol) server that tracks real satellites and checks
whether two of them are on course for a close approach — the same class of
problem commercial space situational awareness (SSA) providers like LeoLabs,
Slingshot Aerospace, and Kayhan Space solve at scale for satellite operators.

This lets any MCP-compatible AI client (Claude Desktop, Claude Code, etc.)
answer questions like:

- "Where is the ISS right now?"
- "Is Starlink-1234 going to pass close to the ISS in the next 24 hours?"
- "Screen these 10 debris objects against my satellite and tell me which ones
  are actually a concern."

## Why this is a real problem, not a toy one

Low Earth Orbit is getting crowded. As of 2024, tracked satellites and debris
routinely produce thousands of close-approach events per year that operators
have to screen and respond to. Real SSA providers run this kind of screening
continuously, at scale, using the same public TLE data and the same SGP4
propagation model this project uses — this server implements the same first
step in that pipeline: a raw miss-distance screen used to flag which pairs of
objects deserve closer attention.

**What this is not:** an operational collision-probability system. Real
systems combine miss distance with each object's position-uncertainty
(covariance) data to compute an actual probability of collision. This
project reports raw miss distance and time of closest approach — the
coarse first filter, not the final word. That distinction is called out
directly in the tool output so it's never presented as more than it is.

## How it works

```
CelesTrak (live TLE data)
        │
        ▼
 tle_fetcher.py   — fetches + caches orbital elements for a satellite
        │
        ▼
 propagator.py    — SGP4 propagation (via Skyfield) → position over time
        │
        ▼
 conjunction.py   — compares two satellites' positions at matching
                     timestamps, finds the closest approach
        │
        ▼
 server.py        — exposes it all as MCP tools
```

- **Data source:** [CelesTrak](https://celestrak.org) — free, public,
  no API key required. The same baseline catalog real SSA providers start
  from.
- **Propagation model:** SGP4, the standard model for TLE-based orbit
  prediction, via the [Skyfield](https://rhodesmill.org/skyfield/) library.
- **Distance calculation:** both satellites are propagated to the *same*
  timestamps in the same reference frame, then compared directly with a
  Euclidean distance — this is what makes the "closest approach" number
  meaningful rather than an apples-to-oranges comparison.

## Tools exposed

| Tool | What it does |
|---|---|
| `get_satellite_tle(norad_id)` | Fetch a satellite's current orbital elements |
| `get_satellite_position(norad_id, timestamp_iso?)` | Lat/lon/altitude at a given time (default: now) |
| `check_conjunction(norad_id_a, norad_id_b, ...)` | Closest approach between two satellites over a time window |
| `screen_conjunctions(primary_norad_id, candidate_norad_ids, ...)` | Screen a list of objects against one primary satellite, ranked by risk |

Every tool takes a **NORAD catalog number** — a public ID every tracked
object has. A few to try:

| Object | NORAD ID |
|---|---|
| International Space Station | 25544 |
| Hubble Space Telescope | 20580 |
| NOAA-20 | 43013 |

Full catalog lookup: [celestrak.org](https://celestrak.org/satcat/search.php)

## Setup

```bash
git clone <this-repo>
cd satellite-conjunction-mcp
pip install -r requirements.txt
```

### Run it directly

```bash
python server.py
```

### Connect it to Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "satellite-conjunction": {
      "command": "python",
      "args": ["/absolute/path/to/satellite-conjunction-mcp/server.py"]
    }
  }
}
```

Restart Claude Desktop, and the four tools above become available in
conversation.

## Running the tests

```bash
pip install pytest
pytest tests/ -v
```

The test suite uses a fixed, real ISS TLE snapshot (not a live fetch) so
it's deterministic and doesn't depend on network access. It checks:

- Propagated altitude falls in the expected LEO range for the ISS
- The time-stepping produces the expected number of samples
- A satellite checked against itself reports ~0 km separation at every
  timestep — the core sanity check that the distance math is correct

## Known limitations

- TLE-based propagation has inherent uncertainty (typically growing from
  ~1 km to several km over days) — it is an estimate, not ground truth.
- Risk thresholds (`HIGH` / `MODERATE` / `LOW`) are illustrative defaults
  for a raw distance screen, not calibrated operational thresholds.
- This does not compute collision *probability* — that requires
  object-specific covariance data this project does not have access to.
- CelesTrak data updates roughly daily; this is not real-time tracking.

## Credits

Built as a learning project to understand real satellite conjunction
assessment — the kind of problem companies like
[LeoLabs](https://leolabs.space), [Slingshot Aerospace](https://slingshotaerospace.com),
and [Digantara](https://digantara.co) solve commercially.

License: MIT