aurora-lens
README.md
<div align="center">
# 🌌 AuroraLens
**The Sun is shouting. AuroraLens listens — live solar-storm + seismic ops on a 3D planet, for humans *and* agents.**
[](https://aurora-lens-ruddy.vercel.app)
[](./LICENSE)
[](https://nextjs.org)
[](https://aurora-lens-ruddy.vercel.app/api/health)
[](https://aurora-lens-ruddy.vercel.app/api/mcp)
[](https://github.com/aniruddhaadak80/aurora-lens/actions)
[Live App](https://aurora-lens-ruddy.vercel.app) · [API](https://aurora-lens-ruddy.vercel.app/api/health) · [MCP](https://aurora-lens-ruddy.vercel.app/api/mcp) · [Issues](https://github.com/aniruddhaadak80/aurora-lens/issues)
</div>
> ⚠️ **Safety note:** AuroraLens is an educational dashboard, not an operational warning
> system. For grid, aviation or satellite decisions, always consult official
> [NOAA SWPC](https://www.swpc.noaa.gov/) alerts directly.
## ✨ Features
- 🛰️ **Live planetary feeds** — NOAA SWPC (Kp, solar wind, X-ray flares, alerts) + USGS M4.5+ quakes, cached API routes, sealed offline fallbacks
- 🧮 **Deterministic storm engine** — 0–100 score from 6 itemized factors; same function serves UI, REST and MCP
- 🤖 **MCP agent interface** — JSON-RPC `initialize` / `tools/list` / `tools/call` + live in-page console
- 🔗 **Hash-chained seals** — `SHA-384(prevSeal ‖ canonicalJson)` on every assessment, replay-verifiable
- 🌍 **Library-grade 3D** — `react-globe.gl` night-earth with quake points, storm arcs, auroral rings, pause-on-drag auto-rotate
- 📡 **Zero keys, zero setup** — clone → install → dev, works offline on first paint
## 🏗️ System architecture
```mermaid
flowchart LR
SWPC[("NOAA SWPC<br/>Kp · wind · flares · alerts")]:::cyan
USGS[("USGS<br/>M4.5+ quakes")]:::cyan
API["Next.js API routes<br/>revalidate cache"]:::slate
FALL["Sealed fallbacks<br/>offline samples"]:::amber
ENG["Storm engine<br/>6 weighted factors"]:::violet
SEAL["Seal chain<br/>SHA-384"]:::emerald
UI["Dashboard UI<br/>hero · gauge · globe"]:::cyan
MCP["MCP endpoint<br/>JSON-RPC tools"]:::emerald
AG["Coding agents<br/>Claude · Codex · goose"]:::emerald
SWPC --> API
USGS --> API
FALL --> API
API --> ENG
ENG --> SEAL
SEAL --> UI
SEAL --> MCP
MCP --> AG
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
classDef slate fill:#94a3b8,color:#04060c;
```
## 🚰 Data-pipeline flow
```mermaid
flowchart TB
POLL["Route handler<br/>revalidate 120–300s"]:::slate
FETCH["Parallel upstream fetch<br/>5 NOAA + 1 USGS endpoints"]:::cyan
NORM["Normalize<br/>shared TypeScript contract"]:::cyan
OK{"All feeds OK?"}:::amber
LIVE["Tag source = live"]:::emerald
BACK["Swap sealed fallback samples"]:::amber
OUT["JSON response<br/>+ fetchedAt + source tag"]:::cyan
POLL --> FETCH
FETCH --> NORM
NORM --> OK
OK -->|yes| LIVE
OK -->|no| BACK
LIVE --> OUT
BACK --> OUT
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
classDef slate fill:#94a3b8,color:#04060c;
```
## 🧮 Engine / algorithm flow
```mermaid
flowchart LR
KP["Kp 0–9<br/>w 0.30"]:::violet
SPD["Wind speed<br/>w 0.20"]:::violet
BZ["Bz southward<br/>w 0.20"]:::violet
FL["Flare class<br/>w 0.15"]:::rose
AL["Alert count<br/>w 0.10"]:::amber
QK["Quake context<br/>w 0.05"]:::slate
SUM["Weighted sum<br/>0–100"]:::violet
LVL["Level<br/>Quiet→Severe"]:::emerald
KP --> SUM
SPD --> SUM
BZ --> SUM
FL --> SUM
AL --> SUM
QK --> SUM
SUM --> LVL
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
classDef rose fill:#fb7185,color:#04060c;
classDef slate fill:#94a3b8,color:#04060c;
```
Factor reference: Kp linear 0–9 · wind 300→800 km/s · Bz 0→−20 nT · flare A/B/C/M/X mapped 2/8/28/62/92 + magnitude fraction · alerts capped at 10 · quakes M4.5→M8 context only (quakes never *cause* storms).
## 🤖 Agent (MCP) sequence
```mermaid
sequenceDiagram
participant Agent as Coding agent
participant MCP as /api/mcp
participant Live as Feed routes
participant Eng as Storm engine
Agent->>MCP: initialize
MCP-->>Agent: server info + protocol
Agent->>MCP: tools/list
MCP-->>Agent: get_space_weather · get_quakes · assess_storm · verify_seal
Agent->>MCP: tools/call assess_storm {}
MCP->>Live: getSpaceWeather + getQuakes
Live-->>MCP: normalized feeds
MCP->>Eng: assessStorm → sealAssessment
Eng-->>MCP: score + factors + seal
MCP-->>Agent: JSON-RPC result
```
## 🔗 Integrity / seal chain
```mermaid
flowchart TB
GEN["Daily genesis<br/>SHA-384 date anchor"]:::slate
C1["Canonical JSON<br/>sorted keys, record 1"]:::cyan
S1["seal₁ = SHA-384<br/>genesis ‖ canonical₁"]:::emerald
C2["Canonical JSON<br/>record 2"]:::cyan
S2["seal₂ = SHA-384<br/>seal₁ ‖ canonical₂"]:::emerald
VER["POST /api/verify<br/>replay → ok:true"]:::violet
GEN --> S1
C1 --> S1
S1 --> S2
C2 --> S2
S2 --> VER
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
classDef slate fill:#94a3b8,color:#04060c;
```
## 🚀 Quickstart
```bash
git clone https://github.com/aniruddhaadak80/aurora-lens
cd aurora-lens
npm install
npm run dev # → http://localhost:3000
```
Zero env vars. No keys. Works offline.
## 🔌 API
```bash
# Health
curl -s https://aurora-lens-ruddy.vercel.app/api/health
# Live space weather (Kp · wind · flares · alerts)
curl -s https://aurora-lens-ruddy.vercel.app/api/space-weather | head -c 400
# Quakes (M4.5+, 24h)
curl -s https://aurora-lens-ruddy.vercel.app/api/quakes | head -c 400
# Sealed storm assessment (score + factors + SHA-384 seal)
curl -s https://aurora-lens-ruddy.vercel.app/api/assessment | head -c 600
# MCP tools/list
curl -s -X POST https://aurora-lens-ruddy.vercel.app/api/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# MCP assess_storm via live feeds
curl -s -X POST https://aurora-lens-ruddy.vercel.app/api/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"assess_storm","arguments":{}}}'
# Verify a seal chain
curl -s -X POST https://aurora-lens-ruddy.vercel.app/api/verify \
-H 'content-type: application/json' \
-d '{"records":[<sealed-assessment>]}'
```
### Agent setup (`mcp.json`)
```json
{
"mcpServers": {
"aurora-lens": {
"url": "https://aurora-lens-ruddy.vercel.app/api/mcp",
"transport": "streamable-http"
}
}
}
```
Tools: `get_space_weather` · `get_quakes` · `assess_storm` · `verify_seal`. A ready-made file lives at [`public/mcp.json`](./public/mcp.json).
## 🧭 User-journey flow
```mermaid
flowchart LR
LAND["Land on hero<br/>live stats + ticker"]:::cyan
SCORE["Read storm score<br/>itemized factors"]:::violet
GLOBE["Spin the planet<br/>quakes + auroral rings"]:::cyan
CONSOLE["Run MCP demo<br/>one click"]:::emerald
VERIFY["Copy seal → verify<br/>trust the chain"]:::emerald
STAR["Star + fork<br/>join the mission"]:::amber
LAND --> SCORE
SCORE --> GLOBE
GLOBE --> CONSOLE
CONSOLE --> VERIFY
VERIFY --> STAR
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
```
## 📁 Project map
```text
src/
app/
page.tsx # narrative page: 01 LIVE → 05 INTEGRITY
layout.tsx # full SEO/OG metadata
api/
health/route.ts # service + endpoint index
space-weather/ # NOAA SWPC normalizer (cached, fallback-sealed)
quakes/ # USGS normalizer (cached, fallback-sealed)
assessment/ # engine + seal over live feeds
verify/ # seal-chain replay
mcp/ # JSON-RPC initialize/tools/list/tools/call
lib/
types.ts # one contract for UI + REST + MCP
live.ts # upstream fetchers
fallback.ts # sealed offline samples
engine.ts # deterministic scorer + SHA-384 seals
components/
StormGlobe.tsx # react-globe.gl, client-only, canvas fallback
GlobeSection.tsx # ssr:false boundary (Next 16 rule)
ScoreGauge.tsx # animated score ring + factor bars
McpConsole.tsx # live in-page agent console
Ticker.tsx # live marquee
public/mcp.json # drop-in agent config
```
## 🚢 Deployment pipeline
```mermaid
flowchart TB
PUSH["git push main"]:::slate
CI["GitHub Actions CI<br/>node 22 · lint · build"]:::cyan
MERGE{"CI green?"}:::amber
VERCEL["Vercel prod deploy<br/>auto-redeploy on push"]:::violet
CHECKS["HTTP verify<br/>/ · health · feeds · MCP · seal"]:::emerald
LIVE["Live on aurora-lens.vercel.app"]:::emerald
PUSH --> CI
CI --> MERGE
MERGE -->|yes| VERCEL
MERGE -->|no| PUSH
VERCEL --> CHECKS
CHECKS --> LIVE
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
classDef slate fill:#94a3b8,color:#04060c;
```
## 🗺️ Roadmap
### Now — *make the wow undeniable*
- [ ] Aurora-oval probability layer on the globe → visitors *see* tonight's aurora zone
- [ ] Flare timeline scrubber → replay the last 7 days of solar anger
- [ ] Submit to MCP directories (Smithery, PulseMCP, mcp.so) → agents discover AuroraLens
```mermaid
flowchart LR
OVAL["Aurora oval<br/>ovation feed"]:::cyan
SCRUB["Flare scrubber<br/>7-day replay"]:::violet
DIRS["MCP directories<br/>Smithery · Pulse"]:::emerald
WOW["10s wow<br/>locked in"]:::amber
OVAL --> WOW
SCRUB --> WOW
DIRS --> WOW
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
```
### Next — *become infrastructure*
- [ ] WebSocket tick stream (`/api/stream`) → dashboards embed live scores
- [ ] Per-grid-zone impact briefs → operators get actionable text, not just numbers
- [ ] Historical storm archive + comparisons (2003 Halloween, 2024 Gannon) → context goes viral
```mermaid
flowchart LR
WS["Tick stream<br/>live sockets"]:::cyan
ZONES["Grid-zone briefs<br/>operator text"]:::rose
ARCH["Storm archive<br/>legendary events"]:::violet
INFRA["AuroraLens<br/>as infrastructure"]:::emerald
WS --> INFRA
ZONES --> INFRA
ARCH --> INFRA
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef rose fill:#fb7185,color:#04060c;
```
### Later — *grow the swarm*
- [ ] A2A agent-to-agent handoffs → planner agents delegate to AuroraLens specialists
- [ ] Community alert webhooks → Discord/Slack aurora pings for your latitude
- [ ] Satellite-drag + GPS-impact estimators → serve the space-ops niche that pays attention
```mermaid
flowchart LR
A2A["A2A handoffs<br/>agent swarm"]:::emerald
HOOKS["Alert webhooks<br/>Discord · Slack"]:::cyan
DRAG["Sat-drag estimator<br/>space-ops niche"]:::violet
SWARM["Aurora swarm<br/>everywhere"]:::amber
A2A --> SWARM
HOOKS --> SWARM
DRAG --> SWARM
classDef cyan fill:#22d3ee,color:#04060c;
classDef violet fill:#a78bfa,color:#04060c;
classDef emerald fill:#34d399,color:#04060c;
classDef amber fill:#fbbf24,color:#04060c;
```
## 🤝 Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md). One rule to remember: **one function, three
consumers** — scoring logic lives in `src/lib/engine.ts` so UI, REST and MCP never drift.
## 📜 License
MIT — see [LICENSE](./LICENSE). Feed data courtesy of **NOAA SWPC** and the **USGS
Earthquake Hazards Program**; this project is not affiliated with either.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues