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.
README
chuk-mcp-celestial
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 hoursdst(bool, optional): Apply daylight saving timelabel(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 latitudelongitude(float): Observer longitudeheight(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 UTCdst(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):
- Path from
CELESTIAL_CONFIG_PATHenvironment variable ./celestial.yaml(current directory)~/.config/chuk-mcp-celestial/celestial.yaml(user config)
Environment variable overrides:
CELESTIAL_PROVIDER- Default providerCELESTIAL_MOON_PHASES_PROVIDER- Provider for moon phasesSKYFIELD_STORAGE_BACKEND- Storage backend (local/s3/memory)SKYFIELD_S3_BUCKET- S3 bucket nameSKYFIELD_S3_REGION- S3 region- See
celestial.yaml.examplefor 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:
-
S3 (Recommended for production) - Cloud storage with AWS S3
- Persistent across deployments
- Shared across multiple instances
- No local disk required
- Easy CDN integration
-
Local - Traditional filesystem storage
- Good for development and offline use
- No cloud dependencies
- Requires local disk space
-
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
--forceto re-download existing files - ✅ Batch download with
--allflag
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:
- Ephemeris files are stored in your configured backend (S3, local, or memory)
- On first use, Skyfield provider downloads files to a local temp cache
- Skyfield reads from the cache for fast calculations
- 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:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and checks (
make check) - Commit your changes
- Push to the branch
- Open a Pull Request
License
MIT License - see LICENSE file for details
Credits
- Built on chuk-mcp-server
- Data provided by US Navy Astronomical Applications Department
- Inspired by chuk-mcp-open-meteo
Links
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。