chuk-mcp-celestial

chuk-mcp-celestial

Provides authoritative astronomical data including moon phases, solar eclipses, and sun/moon rise and set times using the US Navy API or offline Skyfield calculations. It enables users to query Earth's seasons and celestial events for any location and date.

Category
访问服务器

README

chuk-mcp-celestial

PyPI version Python 3.11+ License: MIT

MCP server for US Navy astronomical and celestial data - The definitive celestial MCP server providing moon phases, solar eclipses, sun/moon rise/set times, and Earth's seasons from the official US Navy Astronomical Applications API.

🌐 Try it now - Hosted version available! - No installation required.

Features

🌙 Comprehensive Celestial Data:

  • Moon phases with exact timing (New Moon, First Quarter, Full Moon, Last Quarter)
  • Sun and moon rise/set/transit times for any location
  • Solar eclipse predictions with local circumstances
  • Earth's seasons (equinoxes, solstices, perihelion, aphelion)

Flexible Providers:

  • Navy API - Authoritative US Navy data, all features
  • Skyfield - 28x faster, offline calculations, research-grade accuracy
  • Hybrid mode - Mix providers per-tool (e.g., Skyfield for moon phases, Navy for eclipses)
  • S3 storage - Cloud-based ephemeris storage via chuk-virtual-fs

🔒 Type-Safe & Robust:

  • Pydantic v2 models for all responses - no dictionary goop!
  • Enums for all constants - no magic strings!
  • Full async/await support with httpx
  • Comprehensive error handling

🔗 Multi-Server Integration:

  • Works seamlessly with time and weather servers
  • Combine celestial + time + weather for comprehensive astronomical intelligence
  • Answer complex questions like "Will the moon be visible tonight with current weather?"

Production Ready:

  • 70%+ test coverage with pytest
  • GitHub Actions CI/CD
  • Automated releases to PyPI
  • Type checking with mypy
  • Code quality with ruff

Installation

Comparison of Installation Methods

Method Setup Time Requires Internet Updates Best For
Hosted Instant Yes Automatic Quick testing, production use
uvx Instant Yes (first run) Automatic No local install, always latest
Local 1-2 min Only for install Manual Offline use, custom deployments

Option 1: Use Hosted Version (Recommended)

No installation needed! Use our public hosted version:

{
  "mcpServers": {
    "celestial": {
      "url": "https://celestial.chukai.io/mcp"
    }
  }
}

Option 2: Install via uvx (No Installation Required)

Run directly without installing:

{
  "mcpServers": {
    "celestial": {
      "command": "uvx",
      "args": ["chuk-mcp-celestial"]
    }
  }
}

Option 3: Install Locally

Basic Installation (Navy API only):

# With pip
pip install chuk-mcp-celestial

# Or with uv (recommended)
uv pip install chuk-mcp-celestial

# Or with pipx (isolated installation)
pipx install chuk-mcp-celestial

With Skyfield Support (offline calculations, 28x faster):

# Install with Skyfield and S3 support
pip install "chuk-mcp-celestial[skyfield]"

# Or with uv
uv pip install "chuk-mcp-celestial[skyfield]"

# Download ephemeris files (one-time setup)
python scripts/download_ephemeris.py --backend local

Then configure in your MCP client:

{
  "mcpServers": {
    "celestial": {
      "command": "chuk-mcp-celestial"
    }
  }
}

Optional: Configure hybrid provider mode (create celestial.yaml):

# Use Skyfield for fast queries, Navy API for everything else
default_provider: navy_api
providers:
  moon_phases: skyfield     # 28x faster
  earth_seasons: skyfield   # 33x faster

Quick Start

Claude Desktop Configuration

Choose one of the installation methods above and add to your Claude Desktop config:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%/Claude/claude_desktop_config.json

Hosted version (easiest):

{
  "mcpServers": {
    "celestial": {
      "url": "https://celestial.chukai.io/mcp"
    }
  }
}

uvx version (no install):

{
  "mcpServers": {
    "celestial": {
      "command": "uvx",
      "args": ["chuk-mcp-celestial"]
    }
  }
}

Local installation:

{
  "mcpServers": {
    "celestial": {
      "command": "chuk-mcp-celestial"
    }
  }
}

Then ask questions like:

  • "When is the next full moon?"
  • "What time does the sun rise in Seattle tomorrow?"
  • "Are there any solar eclipses visible from New York in 2024?"
  • "When are the equinoxes this year?"

Using with mcp-cli

Test the server interactively with mcp-cli:

# Using hosted version
uv run mcp-cli --server https://celestial.chukai.io/mcp --provider openai --model gpt-4o-mini

# Using uvx (local execution)
uv run mcp-cli --server celestial --provider openai --model gpt-4o-mini

Example session:

> when does the sunrise tomorrow in london
✓ Completed: get_sun_moon_data (0.50s)

Sunrise in London tomorrow (2025-11-29) is at 07:41 GMT (UTC).

Additional info:
- Begin civil twilight: 07:02 GMT
- Sunset: 15:56 GMT
- Daylight length: about 8 h 15 m

As a Python Library

Using MCP Server Tools (Default Provider)

import asyncio
from chuk_mcp_celestial.server import (
    get_moon_phases,
    get_sun_moon_data,
    get_solar_eclipse_by_date,
    get_earth_seasons,
)

async def main():
    # Get next 4 moon phases (uses configured provider)
    phases = await get_moon_phases(date="2024-12-1", num_phases=4)
    for phase in phases.phasedata:
        print(f"{phase.phase}: {phase.year}-{phase.month:02d}-{phase.day:02d} at {phase.time} UT")

    # Get sun/moon times for Seattle
    data = await get_sun_moon_data(
        date="2024-12-21",
        latitude=47.60,
        longitude=-122.33,
        timezone=-8
    )
    print(f"Moon phase: {data.properties.data.curphase}")
    print(f"Illumination: {data.properties.data.fracillum}")

    # Check eclipse visibility
    eclipse = await get_solar_eclipse_by_date(
        date="2024-4-8",
        latitude=40.71,  # New York
        longitude=-74.01
    )
    print(f"Eclipse: {eclipse.properties.description}")
    print(f"Magnitude: {eclipse.properties.magnitude}")

asyncio.run(main())

Using Providers Directly

import asyncio
from chuk_mcp_celestial.providers import NavyAPIProvider, SkyfieldProvider

async def main():
    # Use Navy API provider
    navy = NavyAPIProvider()
    phases_navy = await navy.get_moon_phases("2024-1-1", num_phases=4)
    print("Navy API moon phases:")
    for phase in phases_navy.phasedata:
        print(f"  {phase.phase}: {phase.year}-{phase.month:02d}-{phase.day:02d} {phase.time}")

    # Use Skyfield provider (faster, offline)
    skyfield = SkyfieldProvider(
        ephemeris_file="de421.bsp",
        storage_backend="memory",  # or "s3" or "local"
        auto_download=True
    )
    phases_skyfield = await skyfield.get_moon_phases("2024-1-1", num_phases=4)
    print("\nSkyfield moon phases:")
    for phase in phases_skyfield.phasedata:
        print(f"  {phase.phase}: {phase.year}-{phase.month:02d}-{phase.day:02d} {phase.time}")

    # Earth seasons with Skyfield (fast!)
    seasons = await skyfield.get_earth_seasons(2024)
    print("\nEarth seasons 2024:")
    for event in seasons.data:
        print(f"  {event.phenom}: {event.year}-{event.month:02d}-{event.day:02d} {event.time}")

asyncio.run(main())

Hybrid Approach (Best of Both Worlds)

import asyncio
from chuk_mcp_celestial.providers import NavyAPIProvider, SkyfieldProvider

async def main():
    # Use Skyfield for fast offline calculations
    skyfield = SkyfieldProvider(storage_backend="local")

    # Use Navy API for features not in Skyfield
    navy = NavyAPIProvider()

    # Fast moon phases from Skyfield
    phases = await skyfield.get_moon_phases("2024-12-1", num_phases=12)

    # Detailed rise/set times from Navy API
    sun_moon = await navy.get_sun_moon_data(
        date="2024-12-21",
        latitude=47.60,
        longitude=-122.33
    )

    # Solar eclipses only from Navy API (not in Skyfield)
    eclipse = await navy.get_solar_eclipse_by_date(
        date="2024-4-8",
        latitude=40.71,
        longitude=-74.01
    )

    print(f"Next moon phase: {phases.phasedata[0].phase}")
    print(f"Sunrise: {sun_moon.properties.data.sundata[0].time}")
    print(f"Eclipse: {eclipse.properties.description}")

asyncio.run(main())

Available Tools

get_moon_phases(date, num_phases)

Get upcoming moon phases starting from a given date.

Parameters:

  • date (str): Start date (YYYY-MM-DD)
  • num_phases (int): Number of phases to return (1-99, default 12)

Returns: MoonPhasesResponse with list of phase data

get_sun_moon_data(date, latitude, longitude, timezone?, dst?, label?)

Get complete sun and moon data for one day at a specific location.

Parameters:

  • date (str): Date (YYYY-MM-DD)
  • latitude (float): Latitude in decimal degrees (-90 to 90)
  • longitude (float): Longitude in decimal degrees (-180 to 180)
  • timezone (float, optional): Timezone offset from UTC in hours
  • dst (bool, optional): Apply daylight saving time
  • label (str, optional): User label for the query

Returns: OneDayResponse (GeoJSON Feature) with sun/moon rise/set/transit times, twilight, moon phase, and illumination

get_solar_eclipse_by_date(date, latitude, longitude, height?)

Get local solar eclipse circumstances for a specific date and location.

Parameters:

  • date (str): Eclipse date (YYYY-MM-DD)
  • latitude (float): Observer latitude
  • longitude (float): Observer longitude
  • height (int, optional): Height above sea level in meters (default 0)

Returns: SolarEclipseByDateResponse (GeoJSON Feature) with eclipse type, magnitude, obscuration, duration, and local circumstances

get_solar_eclipses_by_year(year)

Get a list of all solar eclipses occurring in a specific year.

Parameters:

  • year (int): Year to query (1800-2050)

Returns: SolarEclipseByYearResponse with list of eclipse events

get_earth_seasons(year, timezone?, dst?)

Get Earth's seasons and orbital events for a year.

Parameters:

  • year (int): Year to query (1700-2100)
  • timezone (float, optional): Timezone offset from UTC
  • dst (bool, optional): Apply daylight saving time

Returns: SeasonsResponse with equinoxes, solstices, perihelion, and aphelion

Architecture

No Dictionary Goop

All responses are strongly-typed Pydantic models:

# ❌ Bad (dictionary goop)
phase = data["phasedata"][0]["phase"]

# ✅ Good (typed models)
phase = data.phasedata[0].phase  # IDE autocomplete works!

No Magic Strings

All constants use enums:

from chuk_mcp_celestial.models import MoonPhase, SeasonPhenomenon

# ❌ Bad (magic strings)
if phase == "Full Moon":

# ✅ Good (enums)
if phase == MoonPhase.FULL_MOON:

Async Native

All API calls use async/await with httpx:

async with httpx.AsyncClient() as client:
    response = await client.get(API_URL, params=params, timeout=30.0)
    response.raise_for_status()
    data = response.json()
return PydanticModel(**data)

Provider Architecture

This server supports multiple calculation providers via a factory pattern, allowing you to choose between different astronomical calculation backends:

Available Providers

Provider Speed Accuracy Offline Features
Navy API Standard (~700ms) Authoritative All features
Skyfield Fast (~25ms) Research-grade Moon phases, seasons

Configuration

Create a celestial.yaml file to configure providers:

# Default provider for all tools
default_provider: navy_api

# Per-tool provider configuration (mix and match!)
providers:
  moon_phases: skyfield          # Fast offline calculations
  sun_moon_data: navy_api         # Rise/set times
  solar_eclipse_date: navy_api    # Eclipse circumstances
  solar_eclipse_year: navy_api    # Eclipse catalogs
  earth_seasons: skyfield         # Fast offline seasons

# Skyfield configuration
skyfield:
  # Ephemeris file to use
  ephemeris: de440s.bsp  # 32 MB, covers 1849-2150

  # Storage backend for ephemeris files
  storage_backend: s3    # Options: local, s3, memory

  # S3 configuration (when storage_backend=s3)
  s3:
    bucket: chuk-celestial-ephemeris
    region: us-east-1
    prefix: ephemeris/
    # profile: default  # Optional AWS profile

  # Local directory (when storage_backend=local)
  data_dir: ~/.skyfield

  # Auto-download ephemeris if not present
  auto_download: true

# Navy API configuration
navy_api:
  base_url: https://aa.usno.navy.mil/api
  timeout: 30.0
  max_retries: 3
  retry_delay: 1.0

Config file locations (checked in order):

  1. Path from CELESTIAL_CONFIG_PATH environment variable
  2. ./celestial.yaml (current directory)
  3. ~/.config/chuk-mcp-celestial/celestial.yaml (user config)

Environment variable overrides:

  • CELESTIAL_PROVIDER - Default provider
  • CELESTIAL_MOON_PHASES_PROVIDER - Provider for moon phases
  • SKYFIELD_STORAGE_BACKEND - Storage backend (local/s3/memory)
  • SKYFIELD_S3_BUCKET - S3 bucket name
  • SKYFIELD_S3_REGION - S3 region
  • See celestial.yaml.example for all options

Ephemeris Storage with chuk-virtual-fs

Skyfield requires JPL ephemeris files (~32 MB) for astronomical calculations. This server uses chuk-virtual-fs to provide flexible storage options:

Storage Backends:

  1. S3 (Recommended for production) - Cloud storage with AWS S3

    • Persistent across deployments
    • Shared across multiple instances
    • No local disk required
    • Easy CDN integration
  2. Local - Traditional filesystem storage

    • Good for development and offline use
    • No cloud dependencies
    • Requires local disk space
  3. Memory - In-memory storage for testing

    • Ephemeral storage
    • Fast but non-persistent

Download Ephemeris Files:

# Download recommended ephemeris (de440s.bsp) to S3
python scripts/download_ephemeris.py

# Download all ephemeris files to S3
python scripts/download_ephemeris.py --all

# Download specific ephemeris to S3
python scripts/download_ephemeris.py --file de421.bsp

# Force re-download even if file exists
python scripts/download_ephemeris.py --force

# Download to local filesystem
python scripts/download_ephemeris.py --backend local

# Download all files to local storage
python scripts/download_ephemeris.py --all --backend local

# List available ephemeris files
python scripts/download_ephemeris.py --list

Features:

  • ✅ Auto-creates S3 bucket if it doesn't exist
  • ✅ Skips files that already exist in storage
  • ✅ Use --force to re-download existing files
  • ✅ Batch download with --all flag

Note: For S3 backend, create a .env file with AWS credentials:

cp .env.example .env
# Edit .env with your AWS credentials

Available ephemeris files:

  • de440s.bsp - 32 MB, covers 1849-2150 (⭐ recommended)
  • de421.bsp - 17 MB, covers 1900-2050 (smaller, older)
  • de440.bsp - 114 MB, covers 1550-2650 (most comprehensive)

How it works:

  1. Ephemeris files are stored in your configured backend (S3, local, or memory)
  2. On first use, Skyfield provider downloads files to a local temp cache
  3. Skyfield reads from the cache for fast calculations
  4. Cache persists across provider instances for performance

See COMPARISON_REPORT.md for detailed accuracy and performance comparison between providers.

Deployment

Docker

Build and run with Docker:

# Build Docker image
make docker-build

# Run container
make docker-run

# Or build and run in one command
make docker-up

The server will be available at http://localhost:8000 in HTTP mode.

Fly.io

Deploy to Fly.io:

# First time setup
fly launch

# Set AWS secrets for S3 ephemeris storage
fly secrets set AWS_ACCESS_KEY_ID=your_key AWS_SECRET_ACCESS_KEY=your_secret

# Deploy
make fly-deploy

# Check status
make fly-status

# View logs
make fly-logs

# Open in browser
make fly-open

Configuration (fly.toml):

  • Environment variables for provider settings
  • S3 bucket configuration
  • AWS credentials via fly secrets (not in file)
  • Auto-scales to 0 when not in use

Ephemeris Setup for Production:

# Download ephemeris files to S3 before first deployment
cp .env.example .env
# Edit .env with your AWS credentials
python scripts/download_ephemeris.py --backend s3

# Or download all files
python scripts/download_ephemeris.py --all --backend s3

Development

Setup

# Clone the repo
git clone https://github.com/yourusername/chuk-mcp-celestial
cd chuk-mcp-celestial

# Install with all dependencies (dev + skyfield)
uv sync --extra dev --extra skyfield

# Or with pip
pip install -e ".[dev,skyfield]"

# Set up environment variables for S3 (optional)
cp .env.example .env
# Edit .env with your AWS credentials

# Download ephemeris files for local development
python scripts/download_ephemeris.py --backend local

Testing

# Run tests
make test

# Run tests with coverage
make test-cov

# Run specific test
pytest tests/test_server.py::test_get_moon_phases -v

Code Quality

# Format code
make format

# Run linters
make lint

# Type checking
make typecheck

# Security checks
make security

# Run all checks
make check

Quick Reference

Common Tasks

Download ephemeris files:

# Recommended (auto-select de440s.bsp)
python scripts/download_ephemeris.py

# All files
python scripts/download_ephemeris.py --all

# To S3 (production)
python scripts/download_ephemeris.py --backend s3

# List available files
python scripts/download_ephemeris.py --list

Configure providers (celestial.yaml):

default_provider: navy_api
providers:
  moon_phases: skyfield      # Fast offline
  earth_seasons: skyfield    # Fast offline
  sun_moon_data: navy_api    # Full features
  solar_eclipse_date: navy_api

Environment variables (.env):

# AWS credentials
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_REGION=us-east-1

# Provider selection
CELESTIAL_PROVIDER=navy_api
CELESTIAL_MOON_PHASES_PROVIDER=skyfield

Test provider comparison:

# Run comparison tests
uv run pytest tests/test_provider_comparison.py -v

# See detailed report
cat COMPARISON_REPORT.md

Multi-Server Integration

The chuk-mcp-celestial server works beautifully with other MCP servers to answer complex questions:

Recommended Server Combinations

Celestial + Time + Weather = Complete Astronomical Intelligence

{
  "mcpServers": {
    "celestial": {
      "url": "https://celestial.chukai.io/mcp"
    },
    "time": {
      "url": "https://time.chukai.io/mcp"
    },
    "weather": {
      "url": "https://weather.chukai.io/mcp"
    }
  }
}

Example Multi-Server Queries

1. Moon Visibility with Location Intelligence

Q: "Where will the moon be in Leavenheath Suffolk tonight at 10:30pm?
    Will it be visible and what phase will it be?"

Uses:
- weather server → geocode_location (find coordinates)
- celestial server → get_sun_moon_data (moon position & phase)
- AI reasoning → combine data for comprehensive answer

Result:
✓ Moon will be visible in western sky at 22:30 GMT
✓ Phase: Waxing Gibbous (52% illuminated)
✓ Position: Descending from upper transit at 18:21

2. Sunrise + Current Time

Q: "When does the sun rise in London and what time is it there now?"

Uses:
- time server → get_time_for_timezone (current time in Europe/London)
- celestial server → get_sun_moon_data (sunrise time)
- weather server → geocode_location (confirm location)

Result:
✓ Current time: 21:43:19 GMT
✓ Sunrise tomorrow: 07:41 GMT
✓ Time until sunrise: 9h 58m

3. Eclipse + Weather Forecast

Q: "Will the next solar eclipse be visible from New York, and what will the weather be like?"

Uses:
- celestial server → get_solar_eclipses_by_year, get_solar_eclipse_by_date
- weather server → get_weather_forecast (for eclipse date)
- time server → timezone conversions

Result:
✓ Eclipse visibility and timing
✓ Weather forecast for eclipse day
✓ Optimal viewing conditions

Why Multi-Server Works Better

Single Server Multi-Server Combination
"Moon rises at 12:55 UTC" "Moon rises at 12:55 (7:55am local time)"
"Sunrise at 07:41" "Sunrise at 07:41, currently 21:43, sunset was at 15:56"
"Eclipse on 2024-4-8" "Eclipse on 2024-4-8, weather: partly cloudy, 60% visibility chance"

Server Responsibilities

Celestial Server (this server):

  • 🌙 Moon phases, positions, rise/set times
  • ☀️ Sun rise/set times, twilight, transit
  • 🌑 Solar eclipse predictions and local circumstances
  • 🌍 Earth's seasons and orbital events

Time Server:

  • ⏰ Precise current time with NTP synchronization
  • 🌐 Timezone conversions and DST handling
  • 📅 Date/time calculations

Weather Server:

  • 🗺️ Geocoding (convert place names to coordinates)
  • ⛅ Weather forecasts and current conditions
  • 📊 Historical weather data
  • 💨 Air quality information

Testing Multi-Server Setup

# Test all three servers together
uv run mcp-cli --server celestial,time,weather \
  --provider openai \
  --model gpt-4o-mini

Then ask questions like:

  • "When is sunset in Tokyo and what time is it there now?"
  • "What phase is the moon tonight and will it be cloudy?"
  • "When is the next eclipse visible from London and what's the forecast?"

Data Source

This MCP server uses the official US Navy Astronomical Applications Department API (https://aa.usno.navy.mil/data/api), which provides:

  • Highly accurate astronomical data
  • Historical data from 1700-2100 (varies by endpoint)
  • Solar eclipse data from 1800-2050
  • Official US government source

Comparison with Other Services

Feature chuk-mcp-celestial Other Services
Data Source US Navy (official) Various APIs
Type Safety Full Pydantic models Often dictionaries
Enums Yes (no magic strings) Usually strings
Async Native httpx Mixed
Eclipse Data Local circumstances Often just dates
Historical Range 200-400 years Usually limited
Test Coverage 70%+ Varies

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests and checks (make check)
  5. Commit your changes
  6. Push to the branch
  7. Open a Pull Request

License

MIT License - see LICENSE file for details

Credits

Links

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选