astronomy-mcp-server
Integrates with NASA's JPL Horizons system to provide small-body and spacecraft ephemerides, allowing users to retrieve positional data for asteroids, comets, and spacecraft over specified time ranges.
Public Hosted Server: https://astronomy.caseyjhand.com/mcp
Overview
Observational astronomy for any place and time: sky positions, rise/set and twilight times, moon phases, and the next eclipse, equinox, opposition, or conjunction — or just ask what's visible right now. Computed locally by astronomy-engine, with optional JPL Horizons ephemerides and satellite passes.
Tools
Tool | Description |
| Apparent position of one body or named star: RA/Dec, alt/az, ecliptic, magnitude, phase, Sun elongation, constellation |
| Rise, set, and transit times for a body, plus civil, nautical, and astronomical twilight for the Sun |
| Illuminated fraction, phase name, synodic age, and the next four quarter phases |
| Next eclipses, equinoxes, solstices, moon quarters, oppositions, conjunctions, greatest elongations, or apsides |
| What's up now: naked-eye bodies (and optional bright stars) above the horizon, ranked, with a sky-condition gate |
| Small-body or spacecraft ephemeris from JPL Horizons (opt-in) |
| Visible satellite passes from a CelesTrak element set propagated with SGP4 (opt-in) |
Resources
Resource | Description |
| Reference card for a solar-system body: name, type, mean radius, naked-eye visibility |
Tool-only clients get the same type, radius, and naked-eye fields inline from astronomy_get_sky_position.
Prompts
Prompt | Description |
| Plan a night of stargazing from a place, chaining the astronomy tools with geocoding and weather steps |
Skills
Skill | Description |
Chaining the tools for observing questions: anchoring dates to the observer's local night, what "visible" means per tool, Moon interference, eclipses from a place, and the opt-in Horizons and satellite tools |
Plugin installs load it from skills/; MCP clients that support the Skills extension read it as skill://astronomy-guide/SKILL.md.
Design reference: docs/design.md.
Related MCP server: Precision astronomical ephemeris and planetary positions via the Swiss Ephemeris.
Capability reference
astronomy_get_sky_position tool
body(sun,moon,mercury…pluto) orstaris required, withstarwinning when both are set;starresolves against a bundled 32-star catalog by common name or Bayer designation (Sirius,α CMa), and a miss fails asstar_not_foundlisting the catalogReturns
equatorial, refraction-correctedhorizontal, andeclipticcoordinates plusmagnitude,angular_diameter_arcsec,phase_angle_degrees,illuminated_fraction,sun_elongation_degrees, andconstellationSolar-system bodies also carry
body_metadata, the resource card'stype,mean_radius_km, andnaked_eye; a star has none
astronomy_get_rise_set tool
One
bodysearched forward fromstart(default now) for the nextcountcycles, default 1; 31 are served per call, and acountup to 366 returns the first 31 with a notice naming thestartandcountthat continue the seriesEach cycle carries
rise_utc,set_utc,transit_utc, andtransit_altitude_degrees; a circumpolar or never-rising body getsnullrise/set and anoteinstead of an errorFor
body: "sun",twilightholds civil, nautical, and astronomical dusk/dawn pairs for the night after each cycle's day. When the first day begins afterstart,night_in_progressholds the preceding night, including polar nights without a sunset; the first cycle otherwise carries its own night. Each pair stays within that night, and times beforestartremain included
astronomy_get_moon_phase tool
Geocentric: takes only
time(default now) and an optionaltimezoneReturns
illuminated_fraction,phase_name,age_days,next_quarters, andphase_longitude_degrees(0 new, 180 full), which is not thephase_angle_degreesofastronomy_get_sky_position
astronomy_find_events tool
One
event(solar_eclipse,lunar_eclipse,equinox,solstice,moon_quarter,opposition,conjunction,max_elongation,perigee_apogee) and the nextcountoccurrences, default 1; 20 are served per call, and acountup to 200 returns the first 20 with a notice naming thestartandcountthat continue the series; searches stop at the end of 2100Body-relative events require
body(body_required); a body the event doesn't apply to fails asbody_not_supported, andconjunctionwithbody2takes the Moon or a planet different frombody(invalid_body_pairotherwise) and reportsseparation_degreesEclipses take an optional observer (
latitudeandlongitudetogether, elseincomplete_observer) that addslocal_visibleandcontact_altitudes_degreesEclipses are included when their peak is at or after
start; their contacts may precedestart
astronomy_list_visible tool
Observer coordinates and one evaluation instant,
time(default now, not a window);min_altitude(default 0) andinclude_stars(default false) shape the listReturns
sky_condition(daylight,civil_twilight,nautical_twilight,astronomical_twilight,dark),sun_altitude_degrees, andbodiesranked brightest-and-highest first, each with avisibility_notethat says when daylight, civil twilight, or Sun glare within 15° hides or dims it
astronomy_get_ephemeris tool
designationis passed to Horizons verbatim ("433;"for a numbered asteroid,"DES=1P;CAP"for a periodic comet, a negative SPK-ID for a spacecraft);startdefaults to now,stopto 24 h later, andstepto"1h"(a count plusm,h,d,mo, ory);latitudeandlongitudetogether add alt/azUp to 200 rows per call; when
truncatedis true the notice names thestartto resume from.target_nameis the object Horizons resolvedFails as
ambiguous_designation,observer_is_target,body_not_found,invalid_step,invalid_elevation,time_out_of_range, orrequest_rejected, each naming the input to correctRegistered only when
ASTRONOMY_ENABLE_HORIZONS=true
astronomy_get_satellite_passes tool
Exactly one of
norad_idorname(ISS, Hubble/HST, and Tiangong/CSS resolve directly; other names are matched against CelesTrak, and an ambiguous one fails asambiguous_satellite_namelisting candidates);startmust be within about a month of today, anddaysdefaults to 710 days are searched per call; a
daysup to 30 returns the first 10 with a notice naming thestartanddaysthat continue the searchReturns
norad_id,satellite_name, andpassesthat are visible (sunlit, above 10° elevation, Sun below −6°), each with rise/peak/set times and azimuths,peak_altitude_degrees,duration_seconds,sunlit, andvisible_start_utc/visible_end_utcRegistered only when
ASTRONOMY_ENABLE_SATELLITES=true
astronomy://body/{body} resource
{body}is one ofsun,moon,mercury…pluto, with name completion; anything else fails asunknown_bodyapplication/jsoncard withbody,name,type(star/planet/moon/dwarf),mean_radius_km, andnaked_eye
astronomy_stargazing_plan prompt
Arguments:
locationrequired;date(YYYY-MM-DD) optional, defaults to tonightReturns one user message that chains
astronomy_get_rise_set(sun, then moon),astronomy_get_moon_phase, andastronomy_list_visiblewithinclude_stars, plus the geocoding and weather steps this server doesn't cover
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Astronomy-specific:
Keyless, offline, deterministic core: the five core tools need no network, API key, or rate limit, and return the same answer for the same body, time, and observer
Times outside the engine's high-accuracy span (≈1900–2100) fail as
time_out_of_range; the Horizons tool is bounded by each target's own data span insteadTimes are ISO 8601 UTC, and a value with no zone is read as UTC; pass an IANA
timezone(or setASTRONOMY_DEFAULT_TIMEZONE) to get*_localfields alongside UTC. The server never infers a timezone from coordinatesNo geocoding: resolve a place name to latitude/longitude and a timezone upstream, then pass the coordinates (
elevationdefaults to 0 m)The two opt-in extensions each carry their own timeout and retry; an upstream failure surfaces as
horizons_unavailableorcelestrak_unavailableand never falls back to core output
Agent-friendly output:
Uncertainty preserved:
magnitude,angular_diameter_arcsec,phase_angle_degrees, andilluminated_fractionarenullwhere the engine can't compute them, rendered as "unavailable", never zeroedDeterministic visibility notes:
visibility_notecomes from real magnitude, altitude, sky condition, and Sun elongation, not a synthetic scoreTyped error contracts: each declared failure carries a typed
reasonand a recovery hint, so callers can correct and retryExact values behind rounded text:
format()pairs each rounded figure with its exact value in brackets (RA 4.4116 h [4.411597993526305]), so acontent[]-only client loses no precision
Getting started
Public Hosted Instance
A public instance is available at https://astronomy.caseyjhand.com/mcp — no installation required. It serves Streamable HTTP; each client takes its own config shape.
For Claude Code:
claude mcp add --transport http astronomy-mcp-server https://astronomy.caseyjhand.com/mcpFor Cline (cline_mcp_settings.json):
{
"mcpServers": {
"astronomy-mcp-server": {
"type": "streamableHttp",
"url": "https://astronomy.caseyjhand.com/mcp"
}
}
}For Cursor (mcp.json):
{
"mcpServers": {
"astronomy-mcp-server": {
"url": "https://astronomy.caseyjhand.com/mcp"
}
}
}Claude Desktop adds remote servers under Settings → Connectors.
Self-Hosted / Local
Add the following to your MCP client configuration file. The core tools need no configuration; set ASTRONOMY_ENABLE_HORIZONS and/or ASTRONOMY_ENABLE_SATELLITES to true to register the extensions.
{
"mcpServers": {
"astronomy-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/astronomy-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"astronomy-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/astronomy-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"astronomy-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/astronomy-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No API key. The core is offline, and both extensions (JPL Horizons, CelesTrak) are keyless.
Installation
Clone the repository:
git clone https://github.com/cyanheads/astronomy-mcp-server.gitNavigate into the directory:
cd astronomy-mcp-serverInstall dependencies:
bun installConfigure environment (optional):
cp .env.example .env
# edit .env only to enable the extensions or override a defaultConfiguration
Every variable is optional; the core runs with none set.
Variable | Description | Default |
| Register |
|
| Register |
|
| Fallback IANA timezone when a call omits | none |
| HTTP timeout for Horizons and CelesTrak requests, in ms. |
|
| In-process element-set cache TTL, in ms. The 2 h default follows CelesTrak's refetch guidance. |
|
| JPL Horizons API endpoint. |
|
| CelesTrak GP endpoint. |
|
| Transport: |
|
| HTTP server port. |
|
| HTTP session mode: |
|
| Authentication: |
|
| Log level ( |
|
| Enable OpenTelemetry. |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t astronomy-mcp-server .
docker run --rm -p 3010:3010 astronomy-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/astronomy-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| Prompt definitions ( |
| Offline compute core — |
| JPL Horizons HTTP client (extension). |
| CelesTrak element-set fetch and SGP4 propagation (extension). |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools and resources in the
createApp()arrays insrc/index.tsNormalize raw engine/API values to the domain type; preserve uncertainty as
nulland never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only astronomy calculations: sun, moon, planets, eclipses, twilight and star positions.
MCP server for aerospace calculations: orbital mechanics, ephemeris, DSN operations, ...
Official Divine API MCP for Western Astrology: Natal, Synastry, Transit, Composite, Progressions.
78 astrology calculations, Tarot, symbolic readings and Vedic calendars via two scoped MCP tools.
Related MCP Servers
- AlicenseAqualityFmaintenanceProvides 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.81Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA self-contained MCP server that gives AI agents the ability to calculate high-precision astronomical data. It provides tropical zodiac coordinates, planetary speeds, retrograde detection, and house cusps using the trusted Swiss Ephemeris engine. 100%4AGPL 3.0
- AlicenseAqualityCmaintenanceAstrology MCP server that computes natal charts, transits, synastry, progressions, returns, eclipses, retrogrades, and moon phases from a real ephemeris, enabling AI agents to provide accurate astrological calculations without hallucination.1275 npm1MIT
- AlicenseAqualityBmaintenancePrecision-audited astrology MCP for natal charts, transits, synastry and moon phases. No API key.1091 npmMIT