An MCP server that provides real-time astronomical data, smart stargazing planning, and light pollution analysis for AI agents.
Project description
mcp-stargazing
Calculate the altitude, rise, and set times of celestial objects (Sun, Moon, planets, stars, and deep-space objects) for any location on Earth, with optional light pollution analysis.
Features
- Altitude/Azimuth Calculation: Get elevation and compass direction for any celestial object.
- Rise/Set Times: Determine when objects appear/disappear above the horizon.
- Light Pollution Analysis: Load and analyze light pollution maps (GeoTIFF format).
- Composite Planning: Build a ranked observing plan that combines place quality, weather, moonlight, and top targets.
- Tool Discovery: Inspect registered MCP tools programmatically through
get_tool_catalog. - Code Execution Ready:
- Serializable Returns: All tools return JSON-serializable data (ISO strings for dates), making them directly usable by LLMs.
- Pagination:
analysis_areasupports paging (page,page_size) to handle large datasets efficiently. - Stable Result Handles:
analysis_area.resource_ididentifies the cached non-pagination query so agents can fetch multiple pages safely. - Standardized Responses: Successful calls return
{ "data": ..., "_meta": ... }; business validation failures return{ "error": ..., "_meta": ... }.
- Performance:
- Async Execution: Non-blocking celestial calculations.
- Caching: Intelligent caching for Simbad queries and regional analysis.
- Proxy Support: Native support for HTTP/HTTPS proxies (useful for downloading astronomical data).
- Time Zone Aware: Works with local or UTC times.
- Data Driven: Integrated database of 10,000+ deep-sky objects (Messier & NGC) for smart recommendations.
Installation
This project uses uv for dependency management.
Local Installation
-
Install
uv:pip install uv
-
Sync dependencies:
uv syncThis will create a virtual environment in
.venvand install all dependencies defined inpyproject.toml. -
Activate the environment:
source .venv/bin/activate
-
Initialize Data (Required for Nightly Planner): This downloads the latest Messier and NGC catalog data to
src/data/objects.json.python scripts/download_data.pyNote: If you are behind a firewall, ensure
HTTP_PROXYenv var is set before running this script.
Docker Installation
You can also run the server using Docker, which handles all dependencies and data initialization automatically.
-
Build the image:
docker build -t mcp-stargazing .
Note: If you are behind a proxy, pass the proxy URL during build:
docker build --build-arg HTTP_PROXY=http://127.0.0.1:7890 -t mcp-stargazing .
-
Run the container:
# Basic run (SHTTP mode on port 3001) docker run -p 3001:3001 mcp-stargazing # With Environment Variables docker run -p 3001:3001 \ -e QWEATHER_API_KEY=your_key \ -e STARGAZING_DB_CONFIG=your_db_config \ mcp-stargazing
MCP Server Usage
Start the MCP server to expose tools to AI agents or other clients.
1. Environment Setup
Create a .env file or export variables:
# Weather tools
# 推荐:使用你账号专属的 API Host(公共域名将从 2026 年起逐步停止服务)
export QWEATHER_API_HOST="abc1234xyz.def.qweatherapi.com"
# 鉴权(二选一)
# 1) API KEY(兼容旧用法)
export QWEATHER_API_KEY="your_api_key"
# 2) JWT(推荐,更安全)
# export QWEATHER_JWT_TOKEN="your_jwt_token"
# 如需临时兼容旧公共域名(不推荐),显式开启:
# export QWEATHER_ALLOW_PUBLIC_HOST=1
# Optional: Proxy for downloading astronomical data (Simbad/IERS)
# Highly recommended if you are in a restricted network environment
export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"
2. Start Server
Streamable HTTP (SHTTP) mode (Recommended for most agents):
# Basic start
python -m src.main --mode shttp --port 3001 --path /shttp
# With proxy explicitly passed (overrides env vars)
python -m src.main --mode shttp --port 3001 --path /shttp --proxy http://127.0.0.1:7890
SSE mode:
python -m src.main --mode sse --port 3001 --path /sse
dev mode is no longer supported because current FastMCP versions no longer provide run_dev(). Use local, shttp, or sse.
3. Response Format
Successful business responses return data in a standardized JSON format:
{
"data": {
// Tool-specific return data
"altitude": 45.5,
"azimuth": 180.0
},
"_meta": {
"version": "1.0.0",
"status": "success"
}
}
Business validation failures use the same envelope style:
{
"error": {
"code": "INVALID_TIME_FORMAT",
"message": "Invalid time format: invalid-time-format",
"details": {
"time_string": "invalid-time-format"
}
},
"_meta": {
"version": "1.0.0",
"status": "error"
}
}
At the MCP protocol layer, tools/list and get_tool_catalog are kept aligned, and JSON-RPC request ids are preserved in both SHTTP and SSE transport tests.
4. Available Tools
get_celestial_pos: Calculate altitude/azimuth.get_celestial_rise_set: Calculate rise/set times (Returns ISO strings).get_moon_info: Detailed moon phase, illumination, and age.list_visible_planets: List of all planets currently above the horizon with positions.get_constellation: Find the position (Alt/Az) of a constellation center.get_nightly_forecast: Smart planner returning curated list of best objects to view tonight (Planets + Deep Sky).get_weather_by_name/get_weather_by_position: Fetch current weather with automatic retry on network failures.get_local_datetime_info: Get current local time information.get_tool_catalog: Discover available MCP tool metadata and parameters.get_best_stargazing_plan: Build a ranked regional observing plan with candidate places, weather summaries, best observation windows, and top targets.- Inputs:
south,west,north,east,time,time_zone,candidate_limit,target_limit,weather_provider,max_locations,min_height_diff,road_radius_km,network_type,db_config_path. - Returns:
query,summary, andcandidates, wherequery.analysis_resource_idlinks the plan back to the underlyinganalysis_areasearch when available. - Degradation: Weather or forecast sub-queries may degrade into
summary.warningsand per-candidatenotes, while the overall planning response remains successful.
- Inputs:
light_pollution_map: Query light pollution data for a bounding box area.- Inputs:
south,west,north,east,zoom(default 10). - Returns: A grid of data points with Bortle class, brightness, and SQM values.
- Inputs:
analysis_area: Find best stargazing spots in a region.- Inputs:
south,west,north,east,max_locations,min_height_diff,road_radius_km,network_type,db_config_path,page,page_size. - Returns: List of spots with pagination metadata (
total,page,page_size,total_pages) and aresource_idthat identifies the cached non-pagination query parameters. - Validation:
page >= 1andpage_size >= 1; invalid pagination arguments returnCONFIGURATION_ERROR.
- Inputs:
5. Error Handling
All tools return JSON-serializable data and use structured error handling:
- Standard Error Codes:
INVALID_COORDINATES,INVALID_TIMEZONE,INVALID_TIME_FORMAT,MISSING_API_KEY,API_AUTH_FAILURE,API_TIMEOUT,API_RATE_LIMIT,EXTERNAL_API_ERROR,NETWORK_ERROR,CONFIGURATION_ERROR - Weather Tools: Include automatic retry logic for network failures (up to 3 attempts with exponential backoff)
- Business Error Responses: Structured MCPError-derived payloads with actionable messages for calling agents
- Protocol Tests:
tools/list,get_tool_catalog, and SSE request-id behavior are covered by protocol-level tests - Validation: Input parameters are validated before processing with clear error messages
Examples
-
Nightly Planner:
python examples/nightly_forecast_demo.py- Shows a curated list of planets and deep-sky objects visible tonight, accounting for moonlight.
-
Visible Planets:
python examples/visible_planets_demo.py- Lists which planets are currently up.
-
Moon Info:
python examples/moon_phase_demo.py- Prints a 30-day moon phase calendar.
-
Orchestration:
python examples/code_execution_orchestration.py- Demonstrates a full workflow: Get time -> Get Celestial Pos -> Check Weather -> Find Spots.
- Shows how to handle the standardized response format programmatically.
-
Pagination:
python examples/pagination_demo.py- Demonstrates fetching large result sets page by page using the
resource_id.
- Demonstrates fetching large result sets page by page using the
Project Structure
The project is modularized for better maintainability and code execution support:
.
├── src/
│ ├── functions/ # Tool implementations grouped by domain
│ │ ├── celestial/ # Celestial calculations (pos, rise/set)
│ │ ├── metadata/ # Tool discovery surface (`get_tool_catalog`)
│ │ ├── planning/ # Composite planning tools (`get_best_stargazing_plan`)
│ │ ├── weather/ # Weather API integration
│ │ ├── places/ # Location and area analysis
│ │ └── time/ # Time utilities
│ ├── cache.py # Caching logic for analysis results
│ ├── response.py # Standardized response formatting
│ ├── server_instance.py # FastMCP server instance (avoids circular imports)
│ ├── main.py # Entry point and tool registration
│ ├── celestial.py # Core astronomy logic (Astropy wrappers)
│ ├── placefinder.py # Grid analysis logic
│ └── qweather_interaction.py # Legacy QWeather helpers
├── tests/ # Unified test suite
│ ├── test_celestial.py
│ ├── test_mcp_client.py # MCP protocol and transport contract tests
│ ├── test_server_instance.py # Tool metadata registry behavior
│ ├── test_weather.py
│ ├── test_serialization.py # Validates JSON return formats
│ ├── test_structured_errors.py # Structured business error expectations
│ └── test_integration.py # End-to-end flow tests
├── examples/ # Usage examples
├── docs/ # Documentation and improvement plans
└── pyproject.toml # Project configuration and dependencies
Testing
Run the unified test suite:
uv run pytest -v tests/
Key tests include:
test_serialization.py: Ensures all tools return valid JSON with the correct schema.test_integration.py: Mocks external APIs to verify the entire toolchain.test_mcp_client.py: Verifiestools/list,tools/call, and SSE request-id protocol behavior.test_structured_errors.py: Verifies business validation failures stay in the structured response envelope.
Contributing
- Follow the Code Execution with MCP best practices.
- Ensure all new tools return standard JSON responses using
src.response.format_response. - Add tests in
tests/for any new functionality. - Follow the repository agent conventions in
AGENTS.mdfor all MCP tool and agent-facing changes. - Refer to
docs/ROADMAP.mdfor the planned agent and harness feature roadmap.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_stargazing-0.4.0.tar.gz.
File metadata
- Download URL: mcp_stargazing-0.4.0.tar.gz
- Upload date:
- Size: 169.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b46877a139bbf825c014984e587418c6ce95527eb6448f4cdb11b40995ae00e0
|
|
| MD5 |
830032f2fc692037fb6ee34241b99ab5
|
|
| BLAKE2b-256 |
fa4b3f048ef85bba8f2c53a82505406631642b52cb00e05151b812d4c4df5065
|
Provenance
The following attestation bundles were made for mcp_stargazing-0.4.0.tar.gz:
Publisher:
release-pypi.yml on StarGazer1995/mcp-stargazing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_stargazing-0.4.0.tar.gz -
Subject digest:
b46877a139bbf825c014984e587418c6ce95527eb6448f4cdb11b40995ae00e0 - Sigstore transparency entry: 1980679751
- Sigstore integration time:
-
Permalink:
StarGazer1995/mcp-stargazing@8a0c90a58a71f38d58b8f8ed52f2ac6eaa3fd886 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/StarGazer1995
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@8a0c90a58a71f38d58b8f8ed52f2ac6eaa3fd886 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mcp_stargazing-0.4.0-py3-none-any.whl.
File metadata
- Download URL: mcp_stargazing-0.4.0-py3-none-any.whl
- Upload date:
- Size: 161.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acd44a4d2a2d4101164fef8ffd8bf348865e8c9989e3ae26a7f0f97012c417fa
|
|
| MD5 |
6281e33b4b55480c7dbf43671c9ef858
|
|
| BLAKE2b-256 |
16a0c50c61214a5fb03b4e8f99e4090febdfc67a74dc9a8ba17a0dca7f433e4c
|
Provenance
The following attestation bundles were made for mcp_stargazing-0.4.0-py3-none-any.whl:
Publisher:
release-pypi.yml on StarGazer1995/mcp-stargazing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_stargazing-0.4.0-py3-none-any.whl -
Subject digest:
acd44a4d2a2d4101164fef8ffd8bf348865e8c9989e3ae26a7f0f97012c417fa - Sigstore transparency entry: 1980680069
- Sigstore integration time:
-
Permalink:
StarGazer1995/mcp-stargazing@8a0c90a58a71f38d58b8f8ed52f2ac6eaa3fd886 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/StarGazer1995
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@8a0c90a58a71f38d58b8f8ed52f2ac6eaa3fd886 -
Trigger Event:
push
-
Statement type: