astronomy-mcp-server
Server Details
Offline observational astronomy: positions, rise/set, moon phases, eclipses, and seasons.
- Status
- Healthy
- Uptime
- 100.0% over 42 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/astronomy-mcp-server
- GitHub Stars
- 3
- Server Listing
- astronomy-mcp-server
TDQS
Scored across 7 tools
Most tools target distinct resources and actions, and the descriptions are detailed enough to separate them. The only minor overlap is between astronomy_find_events with moon_quarter events and astronomy_get_moon_phase, both of which can surface upcoming Moon phase timings.
Every tool follows the same pattern: astronomy_ + verb + noun in snake_case (find_events, get_ephemeris, get_moon_phase, get_rise_set, get_satellite_passes, get_sky_position, list_visible). The convention is perfectly consistent and predictable.
Seven tools is a well-scoped size for an astronomy server. Each tool addresses a distinct recurring need—event search, ephemerides, moon phase, rise/set, satellite passes, single-object positions, and whole-sky visibility—without unnecessary redundancy.
The tool surface covers the major observational astronomy workflows: predicting events, getting ephemerides and positions, planning observations with rise/set and twilight, and checking visible sky and satellite passes. Gaps such as geocoding are explicitly delegated upstream, so the set has no critical dead ends for its intended purpose.
Available Tools
7 toolsastronomy_find_eventsastronomy-mcp-server: find sky eventsARead-onlyIdempotentInspect
Search forward from a start time for the next occurrences of one sky-event class, selected by the event enum: solar_eclipse, lunar_eclipse, equinox, solstice, moon_quarter, opposition, conjunction, max_elongation, or perigee_apogee. Both eclipse classes take an optional observer (latitude and longitude together). solar_eclipse without one returns global eclipses — kind, peak time, obscuration, and for a total or annular eclipse the latitude/longitude where it is greatest; with one it returns only eclipses visible from that point, with local contact times, local_visible, and the Sun's altitude at each contact. lunar_eclipse returns geocentric contact times, the same instants everywhere on Earth; an observer adds local_visible and the Moon's altitude at each contact. Every other class is geocentric and ignores a location. The body-relative events (opposition, conjunction, max_elongation, perigee_apogee) require a body: opposition applies to the superior planets (mars through pluto), conjunction to any planet, max_elongation to mercury and venus, and perigee_apogee to the moon (perigee/apogee), earth, or a planet (perihelion/aphelion). Returns the next count occurrences (default 1). Searches stop at the end of 2100, the close of the supported span; when that leaves fewer than count, a notice says so. Start defaults to now; pass an IANA timezone for observer-local timestamps.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Target body — required for opposition, conjunction, max_elongation, and perigee_apogee; ignored otherwise. "earth" is accepted only for perigee_apogee, which returns its perihelion and aphelion. | |
| count | No | Number of forward occurrences to return. Default 1, max 20. | |
| event | Yes | Which class of event to search for. | |
| start | No | Search start as an ISO 8601 UTC string, e.g. "2024-01-01T00:00:00Z". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| latitude | No | Observer latitude in decimal degrees, supplied together with longitude. Optional for solar_eclipse and lunar_eclipse, where it adds local circumstances; omit both for a global solar search. Ignored by every other event. | |
| timezone | No | IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only. | |
| elevation | No | Observer elevation in meters above sea level. Default 0. | |
| longitude | No | Observer longitude in decimal degrees, supplied together with latitude. Optional for solar_eclipse and lunar_eclipse; ignored by every other event. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| events | No | The next occurrences of the requested event class, in chronological order. |
| notice | No | Why the list is shorter than the requested count: the search reached the end of the supported span (2100). Absent when every requested occurrence came back. |
| totalCount | No | Number of event occurrences returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond the schema: the 2100 end-of-span cutoff, the notice when fewer than `count` are found, observer-local timestamp semantics, and the fact that some event classes ignore the observer parameters. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every clause contributes a distinct fact about behavior or parameter usage, and it is front-loaded with the core purpose. It could be tightened by splitting into shorter sentences, but the density is justified for a tool with nine event classes and branching behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the rich output schema, the description covers the major behavioral branches (global vs. local eclipses, geocentric vs. observer-based events, body constraints, count cutoff, timezone defaults). The only notable gap is that elevation is not mentioned in the description narrative, though it is documented in the schema; since schema coverage is 100%, this is a minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description substantially enriches parameter understanding: it explains that latitude/longitude are required together, that they are only meaningful for the two eclipse classes, that `body` is required only for four event classes and is accepted for `earth` only in perigee_apogee, and how `timezone` changes output. This is genuine semantic guidance beyond the schema field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Search forward from a start time') and a specific resource ('one sky-event class, selected by the `event` enum'), and it enumerates the exact event classes. It clearly distinguishes the tool from the sibling tools, which cover ephemerides, moon phase, rise/set, satellite passes, and sky position.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance for each event class: it explains which events accept an observer, which events require a `body`, which bodies apply to which event, and the special behavior of solar vs. lunar eclipses. It also covers the 'every other class is geocentric and ignores a location' rule, leaving little ambiguity about how to choose parameters for a call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
astronomy_get_ephemerisastronomy-mcp-server: get small-body ephemerisARead-onlyIdempotentInspect
Fetch a time-series ephemeris for a small body (asteroid or comet) or spacecraft from JPL Horizons — RA/Dec, distance, and apparent magnitude over a span, optionally with observer-relative altitude/azimuth. This covers objects the in-process major-body set cannot. The designation is passed to Horizons verbatim, so it must be in a form Horizons resolves to a single record: a numbered asteroid takes a trailing-semicolon record lookup (e.g. "433;" for Eros, "1;" for Ceres), and a periodic comet takes the DES + closest-apparition form (e.g. "DES=1P;CAP" for Halley). Spacecraft take their negative SPK-ID. Anything else goes through the Horizons name search: a bare name matching nothing (e.g. "433 Eros") or several records (e.g. "1P/Halley") is rejected, but one matching a single object succeeds even when that object is not the one meant — "Eros" resolves to Kerberos, a moon of Pluto — so compare target_name, the object Horizons resolved, with the one intended. start and stop are ISO 8601 UTC and stop must be after start; step is a count plus a unit of m, h, d, mo, or y, such as "1d", "1h", or "10m". Supplying observer latitude/longitude yields topocentric coordinates and adds alt/az — supply both or neither. This is a gated, network-backed extension (JPL Horizons is keyless but rate-limited and best-effort); large spans truncate inline at 200 rows, and the truncation notice names the exact start to resume from — one step past the last row returned, because Horizons includes the start instant in its output — so re-calling from there continues the series without repeating a sample. Splitting the range into smaller adjacent spans works too; keep the same step either way so no sample is lost.
| Name | Required | Description | Default |
|---|---|---|---|
| step | No | Step size as a positive count plus a unit of m (minutes), h (hours), d (days), mo (months), or y (years), e.g. "10m", "1h", "1d". Default "1h". | 1h |
| stop | No | Ephemeris stop as an ISO 8601 UTC string, and must be later than start. Defaults to 24 hours after start. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| start | No | Ephemeris start as an ISO 8601 UTC string, e.g. "2024-01-01T00:00:00Z". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| latitude | No | Observer latitude in decimal degrees — supply together with longitude for topocentric coordinates and alt/az. Supplying one without the other is rejected. | |
| elevation | No | Observer elevation in meters above sea level. Default 0. | |
| longitude | No | Observer longitude in decimal degrees. Supply together with latitude; one without the other is rejected. | |
| designation | Yes | JPL Horizons target, passed verbatim — use a form that resolves to one record. Numbered asteroid: trailing-semicolon record lookup, e.g. "433;" (Eros), "1;" (Ceres). Periodic comet: DES + closest-apparition flag, e.g. "DES=1P;CAP" (Halley), "DES=2P;CAP" (Encke). Spacecraft: negative SPK-ID, e.g. "-48" (Hubble). A bare name like "433 Eros" (no match) or "1P/Halley" (several records) is rejected, but one matching a single object succeeds even when it is not the object meant — check `target_name` in the result. Look up designations at ssd.jpl.nasa.gov/tools/sbdb_lookup.html. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The inline row cap that was applied. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of ephemeris rows returned. |
| notice | No | Caveats on the returned series — how to retrieve rows omitted by the cap, and whether any rows were dropped. Absent when the whole span came back intact. |
| points | No | Time-series of positions, one per step, in chronological order. |
| dropped | No | Rows Horizons returned that carried no usable time, position, or distance and were dropped. Present only when at least one row was dropped, in which case the series has gaps and is shorter than the requested step count. |
| truncated | No | True when Horizons returned more rows than the inline cap. |
| designation | No | The body designation echoed from the request. |
| target_name | No | The object JPL Horizons resolved the designation to, from its 'Target body name' header — compare it with the intended object, since a bare name can resolve to a different one. Absent when Horizons' response names no target. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, the description adds substantial behavioral context: the tool is gated and network-backed, Horizons is keyless but rate-limited and best-effort, large spans truncate at 200 rows, and the truncation notice names the exact start to resume from. There is no contradiction; the description enriches the annotation profile meaningfully.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place given the tool's complexity. It front-loads the core purpose in the first sentence, then layers the necessary resolution rules, validation constraints, network behavior, and pagination details in a logical order. There is no filler or repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, network-backed, gated tool with 7 parameters and an output schema, the description is remarkably complete. It covers designation resolution, date/step constraints, topocentric coordinates, rate-limiting, truncation, and resumption strategy. Since an output schema exists, the description does not need to explain return values, and nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds value beyond the schema by explaining the trailing-semicolon asteroid convention, DES+CAP comet forms, negative SPK-ID for spacecraft, and the ambiguity pitfall with examples like '433 Eros' and 'Eros'. It reinforces the start/stop/step semantics and the topocentric coordinate coupling rule, making the parameters more usable than the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a precise verb and resource: 'Fetch a time-series ephemeris for a small body (asteroid or comet) or spacecraft from JPL Horizons.' It specifies the output dimensions (RA/Dec, distance, magnitude, optional alt/az) and clearly differentiates the tool by stating it covers objects the in-process major-body set cannot, which distinguishes it from sibling tools like astronomy_get_sky_position.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives extensive when-to-use guidance: small bodies and spacecraft not in the major-body set. It also covers when-not-to-use scenarios, such as ambiguous or unmatched designations, and even explains how to verify the resolved target via `target_name`. This goes well beyond mere context and provides actionable selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
astronomy_get_moon_phaseastronomy-mcp-server: get moon phaseARead-onlyIdempotentInspect
Report the Moon phase for an instant: illuminated fraction, phase name, synodic age in days since the new moon, phase longitude (the Moon–Sun ecliptic-longitude difference, 180° at full), and the next four quarter phases (new, first quarter, full, last quarter) with timestamps. Answers "what is the moon phase tonight" and "when is the next full moon" in one call without iteration. The time defaults to now; pass an IANA timezone to also receive observer-local timestamps. The phase is geocentric — no observer location is needed.
| Name | Required | Description | Default |
|---|---|---|---|
| time | No | Instant to evaluate as an ISO 8601 UTC string, e.g. "2024-12-15T00:00:00Z". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| timezone | No | IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| age_days | No | Synodic age in days since the previous new moon. |
| time_utc | No | The instant the phase was computed for, in ISO 8601 UTC. |
| phase_name | No | Human-readable phase name (New Moon, Waxing Crescent, First Quarter, …, Waning Crescent). |
| time_local | No | The same instant in the observer-local timezone with offset, present only when a timezone was supplied. |
| next_quarters | No | The next four lunar quarter phases (new/first/full/last) in chronological order. |
| illuminated_fraction | No | Fraction of the lunar disc illuminated, 0 to 1. |
| phase_longitude_degrees | No | The Moon's ecliptic longitude minus the Sun's, in degrees [0,360): 0 = new, 90 = first quarter, 180 = full, 270 = last quarter. Not the Sun–body–observer phase angle astronomy_get_sky_position reports as phase_angle_degrees, which reads 0 at full moon. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds substantial behavioral context: time defaults to now, a value with no zone designator is read as UTC, timezone produces observer-local timestamps, and the phase is geocentric. It also spells out the output fields, which is valuable despite the output schema. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but every sentence earns its place. It front-loads the core output list, then gives use cases, then parameter behavior. The structure is logical and not padded. It could be trimmed slightly but is well-organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, the presence of an output schema, and the annotations, the description is fully complete. It covers parameters, defaults, timezone semantics, and the geocentric nature, leaving no ambiguity about how to call it or what to expect. An agent can confidently invoke it without further research.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. However, the description adds meaningful details beyond the schema: it clarifies the default for time, the UTC interpretation for missing zone designators, and the effect of timezone on output. These are practical nuances that help an agent use the parameters correctly, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Report') and a clear resource ('Moon phase'), enumerating exactly what data it returns: illuminated fraction, phase name, synodic age, phase longitude, and next four quarter phases. This is far beyond a generic 'get moon phase' and distinguishes it from siblings like astronomy_get_ephemeris or astronomy_get_rise_set, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly mentions typical queries ('what is the moon phase tonight' and 'when is the next full moon') and explains that a single call covers both without iteration. It also notes that the phase is geocentric and no observer location is needed, which implicitly tells agents when to prefer this over location-dependent tools. It stops short of explicitly naming alternative tools or exclusions, so it doesn't reach a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
astronomy_get_rise_setastronomy-mcp-server: get rise/set timesARead-onlyIdempotentInspect
Compute rise, set, and culmination (transit) times for a body at an observer location, plus the maximum altitude at culmination. For the Sun, also returns the three twilight pairs (civil −6°, nautical −12°, astronomical −18°) so a single call answers "when does the sun set and when is it truly dark." Each pair covers the night after the cycle's set — dusk that evening, dawn the next morning — so the dawn listed beside a sunrise is the following day's; for the dawn before a sunrise, read the previous cycle or start a day earlier. Searches forward from start (default today) and returns the next count cycles (default 1). When the body is already above the horizon at start, the first cycle is the interval in progress: its set is the imminent one and its rise is null, since that rise precedes the search — so a set is never reported earlier than the rise beside it. Circumpolar or never-rises situations are reported as null rise/set fields with an explanatory note rather than an error — the fact is the answer. Default elevation is 0 m; pass an IANA timezone for observer-local times. This server does not geocode — resolve coordinates upstream first.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | The body to compute rise/set for. Twilight is included only when this is "sun". | |
| count | No | Number of forward rise/set cycles to return. Default 1, max 31. | |
| start | No | Search start as an ISO 8601 UTC string, e.g. "2024-06-21T00:00:00Z". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| latitude | Yes | Observer latitude in decimal degrees, north positive. | |
| timezone | No | IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only. | |
| elevation | No | Observer elevation in meters above sea level. Default 0. | |
| longitude | Yes | Observer longitude in decimal degrees, east positive. |
Output Schema
| Name | Required | Description |
|---|---|---|
| body | No | The body these rise/set cycles are for, echoed from the request. |
| error | No | Present when the call failed. Absent on success. |
| events | No | One entry per rise/set/transit cycle, searching forward from the start time. |
| totalCount | No | Number of rise/set cycles returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only and idempotent behavior; the description adds substantial behavior beyond that: forward search from `start`, cycle semantics when the body is already above the horizon (null rise with imminent set), circumpolar cases returning explanatory notes instead of errors, and the twilight-pair date meaning (dusk same evening, dawn next day). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every clause earns its place: edge cases, defaults, twilight semantics, and the geocoding limitation are all consequential for a correct call. The primary purpose is front-loaded in the first sentence, and the rest flows logically from output content to search behavior to fallback handling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with an output schema already present, the description covers all non-obvious invocation concerns: search direction, in-progress cycles, circumpolar behavior, timezone output, elevation defaults, and coordinate resolution. Nothing needed to call the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema documents each field's type and default. The description still adds value by tying `start` and `count` together ('Searches forward from `start`... returns the next `count` cycles') and clarifying twilight appears only for `body: "sun"`. These are semantic clarifications beyond the schema's per-field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Compute rise, set, and culmination (transit) times for a body at an observer location,' making the tool's function unmistakable. It does not explicitly contrast with siblings like astronomy_get_ephemeris or astronomy_get_sky_position, so it stops short of full differentiation, but the purpose is clear enough from name and content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when the tool applies (rise/set/culmination queries, including twilight for the Sun) and states a prerequisite: 'This server does not geocode — resolve coordinates upstream first.' It does not explicitly name alternatives or when-not-to-use conditions compared to sibling tools, so it misses the top bar for explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
astronomy_get_satellite_passesastronomy-mcp-server: get satellite passesARead-onlyIdempotentInspect
Predict visible passes of a satellite (e.g. the ISS, NORAD 25544) over an observer in the next days. Identify the satellite by exactly one of norad_id or name — supplying both, or neither, is rejected. A few well-known common names resolve directly to their catalog numbers, ignoring case: ISS or International Space Station (25544), Hubble, Hubble Space Telescope, or HST (20580), and Tiangong, CSS, or Chinese Space Station (48274). Any other name is matched as a case-insensitive substring of CelesTrak's catalog names, so it resolves only when it picks out a single object: a broader query comes back with the matching objects and their catalog numbers to choose from. Either way the result echoes the query that resolved it as resolved_from_name. Fetches the object's current GP element set from CelesTrak, propagates it with SGP4 in-process, and returns each pass's rise, peak, and set times with azimuths and the peak elevation. Only passes that are naked-eye-plausible are returned — the satellite must be sunlit at peak while the observer's sky is dark. Every returned pass rises within the requested window: a pass already underway at start is omitted rather than reported with start as its rise, so back up start to see it, while a pass still up when the window ends is reported through its actual set. A start further than about a month from the element set's epoch is rejected as out of range on that distance alone, and an element set that will not propagate to a window inside that horizon is rejected as a reentry — so an empty passes means only that nothing was visible. CelesTrak publishes only current element sets, so in practice start must be within about a month of today. NORAD catalog numbers and catalog names are found at celestrak.org or heavens-above.com. This is a gated, network-backed extension (CelesTrak is keyless but rate-limited; element sets are cached briefly). Default elevation 0 m; pass an IANA timezone for observer-local pass times.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Number of days ahead to search for passes. Default 7, max 10. | |
| name | No | Satellite name to resolve, e.g. "ISS (ZARYA)". The common names ISS, International Space Station, Hubble, Hubble Space Telescope, HST, Tiangong, CSS, and Chinese Space Station resolve directly to their catalog numbers, ignoring case and surrounding whitespace. Any other name is matched against CelesTrak as a case-insensitive substring of the catalog name, so give the fullest name you have — a short one matches many objects and is rejected as ambiguous. Mutually exclusive with `norad_id` — supply exactly one. | |
| start | No | Search start as an ISO 8601 UTC string, within about a month of the current element set's epoch — for a tracked object that epoch is hours old, so in practice within about a month of today. A start further out is rejected rather than answered from elements that no longer describe the orbit. Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| latitude | Yes | Observer latitude in decimal degrees, north positive. | |
| norad_id | No | NORAD catalog number of the satellite, e.g. 25544 for the ISS. Found at celestrak.org or heavens-above.com. Mutually exclusive with `name` — supply exactly one. | |
| timezone | No | IANA timezone for localized pass times, e.g. "America/Los_Angeles". When omitted, output is UTC-only. | |
| elevation | No | Observer elevation in meters above sea level. Default 0. | |
| longitude | Yes | Observer longitude in decimal degrees, east positive. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| passes | No | Visible passes (sunlit satellite over a dark-enough sky) in the requested window, chronological. |
| norad_id | No | The NORAD catalog number echoed from the request. |
| totalCount | No | Number of visible passes found in the window. |
| satellite_name | No | Satellite name as CelesTrak catalogs it (the element set's OBJECT_NAME). |
| resolved_from_name | No | The name query that resolved this object. Present only when the request supplied `name` rather than `norad_id`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description exceeds annotations by disclosing network dependency, rate limits, caching, and gated access; visibility filtering (sunlit at peak, dark sky); pass-window edge cases; and rejection reasons for out-of-range start or reentry. No contradiction with readOnlyHint, idempotentHint, or openWorldHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded with purpose and key constraints; each paragraph covers a coherent topic. Some sentences rephrase schema defaults (elevation, timezone) and could be trimmed, but the density is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, network-backed tool with 8 parameters, the description covers identification rules, filtering behavior, edge cases, network implications, and output semantics. An output schema exists, so the description need not enumerate return fields; nothing an agent needs to call it correctly appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds real semantics beyond the schema by explaining name resolution rules, the oneOf constraint, start-window behavior, and observer elevation/timezone defaults. It doesn't go into every parameter detail, but supplies integration logic the schema omits.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states the tool predicts visible satellite passes over an observer within a given window, naming the ISS as an example. It clearly distinguishes from siblings like astronomy_get_rise_set or astronomy_get_ephemeris by focusing on satellite passes with visibility criteria.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides detailed usage constraints: exactly one of norad_id or name must be supplied, both/neither rejected; common names resolve directly; ambiguous names return options; start window constrained to about a month; passes already underway omitted; network/rate-limit context. However, it never explicitly names sibling tools or says when not to use this tool in favor of another, so it stops short of 'when/when-not' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
astronomy_get_sky_positionastronomy-mcp-server: get sky positionARead-onlyIdempotentInspect
Compute the apparent topocentric position of one solar-system body (sun, moon, mercury through neptune, pluto) or a named bright star for an observer location and instant. Returns equatorial (RA/Dec), refraction-corrected horizontal (altitude/azimuth), and ecliptic coordinates, plus distance, apparent magnitude, angular diameter, phase angle, illuminated fraction, angular distance from the Sun, and the constellation it falls in. For a solar-system body it also returns that body card — classification, mean radius, naked-eye visibility — the same values served at astronomy://body/{body}, so a client without resource support does not need a second surface to reach them; a catalog star has no card and the field is absent. Positions are parallax- and aberration-corrected for the given observer; default elevation is 0 m and the default time is now. Supply star (e.g. "Sirius", "Polaris") instead of body to target a catalog star; body is ignored when star is set. Pass an IANA timezone to also receive the observer-local time. This server does not geocode — resolve a place name to latitude/longitude upstream first.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Solar-system body to locate. Omit when targeting a named star via `star`. | |
| star | No | Named star to locate, from a bundled catalog of 32 stars — about 30 of the brightest naked-eye stars plus Polaris, not an arbitrary star. Accepts a common name or Bayer designation, with the Greek letter spelled out or as a symbol and the constellation as its genitive or IAU abbreviation (e.g. "Sirius", "Alpha Centauri", "α CMa"). A name outside the catalog fails with the full list of catalog stars. Takes precedence over `body`. | |
| time | No | Instant of observation as an ISO 8601 UTC string, e.g. "2024-04-08T18:00:00Z". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| latitude | Yes | Observer latitude in decimal degrees, north positive. | |
| timezone | No | IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only. | |
| elevation | No | Observer elevation in meters above sea level. Default 0. | |
| longitude | Yes | Observer longitude in decimal degrees, east positive. |
Output Schema
| Name | Required | Description |
|---|---|---|
| body | No | The body or star this position is for, echoed from the request. |
| error | No | Present when the call failed. Absent on success. |
| ecliptic | No | Ecliptic-of-date coordinates of the body. |
| time_utc | No | The instant of the observation in ISO 8601 UTC. |
| magnitude | No | Apparent visual magnitude (lower is brighter). Null for bodies where the engine cannot compute it. |
| equatorial | No | Apparent equatorial coordinates, corrected for precession, nutation, parallax, and aberration. |
| horizontal | No | Refraction-corrected horizontal coordinates as seen from the observer. |
| time_local | No | The same instant in the observer-local timezone with offset, present only when a timezone was supplied. |
| body_metadata | No | The body card also served at astronomy://body/{body}, copied here so a client without resource support can reach it. Present for the ten solar-system bodies; absent for a catalog star, which has no card. |
| constellation | No | The constellation the body currently falls within. |
| phase_angle_degrees | No | Sun-body-observer phase angle in degrees. Null when not applicable (e.g. stars). |
| illuminated_fraction | No | Fraction of the disc illuminated, 0 to 1. Null when not applicable. |
| sun_elongation_degrees | No | Angular distance from the Sun in degrees [0,180], seen from Earth's center. A body within about 15° of the Sun is lost in its glare. 0 for the Sun itself. |
| angular_diameter_arcsec | No | Apparent angular diameter of the disc in arcseconds. Null for point-source convention bodies. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, but the description adds substantial behavioral context: positions are parallax- and aberration-corrected, default elevation is 0 m, default time is now, `body` is ignored when `star` is set, timezone affects output local time, catalog stars produce no body card, and invalid star names fail with a full list. These details go well beyond the structured annotations and are consistent with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but warranted for a 7-parameter tool with many outputs. It is front-loaded with the core purpose, then output details, then defaults and precedence, and ends with a practical geocoding note. Each sentence carries necessary information; the length is justified by complexity, but it is not as tight as a two-sentence minimal description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description does not need to document return shapes, but it still lists all returned quantities (including body-card details). It covers defaults, star/body precedence, timezone behavior, catalog constraints, and the no-geocoding limitation. For a tool of this complexity, there are no obvious gaps an agent would need to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful interplay between `body` and `star` (precedence), explains the effect of `timezone` on output, and clarifies that latitude/longitude must be pre-resolved (no geocoding). This extra semantics raises it above baseline, though it does not radically rewrite parameter meanings.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Compute the apparent topocentric position of one solar-system body ... or a named bright star for an observer location and instant.' It enumerates the exact output quantities (RA/Dec, horizontal, ecliptic, distance, magnitude, etc.) and scopes the tool to a single body or star at a single instant. This clearly distinguishes it from siblings like astronomy_get_ephemeris (time series) or astronomy_get_moon_phase (only lunar phase).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: this tool targets a single body/star for one observer location and instant, and it explicitly tells users to geocode upstream ('This server does not geocode — resolve a place name to latitude/longitude upstream first.'). It also explains the star-vs-body precedence. However, it never names sibling tools or states when to prefer one of them, so it falls short of full explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
astronomy_list_visibleastronomy-mcp-server: list visible bodiesARead-onlyIdempotentInspect
The one-call "what is up right now" answer. For an observer location and instant, iterate every naked-eye solar-system body (and, with include_stars, the bundled bright stars), compute altitude and azimuth, keep those above the horizon, rank them brightest-and-highest first, and attach a plain-language visibility note to each, along with its angular distance from the Sun. The whole sky is gated by the Sun's altitude into daylight / civil / nautical / astronomical twilight / dark, returned alongside the list, and each note says when daylight, civil twilight, or the Sun's glare hides or dims that body. time is a single evaluation instant, not a window — for "tonight" pass a time after astronomical dusk (use astronomy_get_rise_set on the sun to find it). Default elevation 0 m; use min_altitude to skip objects grazing the horizon. This server does not geocode — resolve coordinates upstream first; pass an IANA timezone for observer-local times on each body.
| Name | Required | Description | Default |
|---|---|---|---|
| time | No | Evaluation instant as an ISO 8601 UTC string, e.g. "2024-08-12T05:00:00Z". Defaults to now. A single instant, not a window. A value with no zone designator is read as UTC, not the local zone of the server process. | |
| latitude | Yes | Observer latitude in decimal degrees, north positive. | |
| timezone | No | IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only. | |
| elevation | No | Observer elevation in meters above sea level. Default 0. | |
| longitude | Yes | Observer longitude in decimal degrees, east positive. | |
| min_altitude | No | Minimum altitude in degrees to include a body. Default 0 (above the horizon); use e.g. 5 to require clearance. | |
| include_stars | No | Include the bundled bright stars alongside planets. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| bodies | No | Every body (and optional star) above the minimum-altitude filter, ranked brightest-and-highest first. |
| total_count | No | Number of bodies returned above the minimum-altitude filter. |
| sky_condition | No | Sky condition derived from the Sun's altitude — the gate for whether faint objects are observable. |
| sun_altitude_degrees | No | The Sun's altitude in degrees that produced the sky condition. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description explains how the sky is gated by the Sun's altitude into daylight/twilight/dark, how visibility notes are generated, that time is a single instant not a window, that unzoned times are read as UTC, and that the server does not geocode. This gives the agent exactly the operational context it needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence carries distinct information: scope, ranking/notes, time semantics, defaults, and geocoding constraint. It is front-loaded with the core purpose and scales naturally to the complexity of a 7-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations, the 100%-covered input schema, and the existence of an output schema, the description supplies the remaining context: timezone behavior, no-geocoding limitation, twilight gating, and how to plan 'tonight' observations. Nothing an agent needs to invoke this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful operational meaning: time must be a single instant, min_altitude is for skipping horizon-grazing objects, elevation defaults to 0 m, and timezone controls observer-local output. This raises it above baseline while the schema still carries the formal definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('list visible bodies' for an observer location and instant) and immediately frames it as the one-call 'what is up right now' answer, which distinguishes it from ephemeris, rise/set, and event tools. It clearly specifies scope: naked-eye solar-system bodies, optional bright stars, horizon filtering, ranking, and visibility notes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete conditions: use a single evaluation instant, pass a time after astronomical dusk for 'tonight', and consult astronomy_get_rise_set on the sun to find that time. It also tells users to geocode upstream and to use min_altitude to avoid horizon-grazing objects. It does not enumerate when every sibling should be chosen instead, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
- Changed
astronomy_get_moon_phase3 fields changed- changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "time_utc", - "phase_angle_degrees", - "illuminated_fraction", - "phase_name", - "age_days", - "next_quarters" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "time_utc", + "phase_longitude_degrees", + "illuminated_fraction", + "phase_name", + "age_days", + "next_quarters" + ] + }, + { + "required": [ + "error" + ] + } +] - removed
Output schema / properties / phase_angle_degreesRemoved value: -{ - "description": "Moon phase angle in degrees: 0 = new, 90 = first quarter, 180 = full, 270 = last quarter.", - "type": "number" -} - added
Output schema / properties / phase_longitude_degreesAdded value: +{ + "description": "The Moon's ecliptic longitude minus the Sun's, in degrees [0,360): 0 = new, 90 = first quarter, 180 = full, 270 = last quarter. Not the Sun–body–observer phase angle astronomy_get_sky_position reports as phase_angle_degrees, which reads 0 at full moon.", + "type": "number" +}
- Changed
astronomy_get_rise_set16 fields changed- changed
Output schema / properties / events / items / properties / twilight / descriptionPrevious value: -"The three twilight pairs. Present only when body is \"sun\"."New value: +"The three twilight pairs, present only when body is \"sun\". Each pair spans one night: dusk is the evening of this cycle's set and dawn is the following morning, so a cycle's dawn falls a day after its rise. The dawn before a given sunrise is in the previous cycle's pair — start the search a day earlier to get it." - changed
Output schema / properties / events / items / properties / twilight / properties / astronomical / descriptionPrevious value: -"Astronomical twilight (Sun at −18°) dawn and dusk — the dark-sky window."New value: +"Astronomical twilight (Sun at −18°): dusk and the following dawn, bounding the dark-sky window." - changed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dawn_local / descriptionPrevious value: -"Dawn in observer-local time, present only when a timezone was supplied."New value: +"Dawn in observer-local time — the morning after the cycle's set — present only when a timezone was supplied." - changed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dawn_utc / descriptionPrevious value: -"Dawn (Sun ascending through the depth) in ISO 8601 UTC, or null if it does not occur."New value: +"Dawn (Sun ascending through the depth) in ISO 8601 UTC, or null if it does not occur. This is the morning after the cycle's set, ending the night that begins at the dusk beside it — a day later than the cycle's rise, not the dawn before it." - changed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dusk_local / descriptionPrevious value: -"Dusk in observer-local time, present only when a timezone was supplied."New value: +"Dusk in observer-local time — the evening of the cycle's set — present only when a timezone was supplied." - changed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dusk_utc / descriptionPrevious value: -"Dusk (Sun descending through the depth) in ISO 8601 UTC, or null if it does not occur."New value: +"Dusk (Sun descending through the depth) in ISO 8601 UTC, or null if it does not occur. This is the evening of the cycle's set." - changed
Output schema / properties / events / items / properties / twilight / properties / civil / descriptionPrevious value: -"Civil twilight (Sun at −6°) dawn and dusk."New value: +"Civil twilight (Sun at −6°): dusk and the following dawn." - changed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dawn_local / descriptionPrevious value: -"Dawn in observer-local time, present only when a timezone was supplied."New value: +"Dawn in observer-local time — the morning after the cycle's set — present only when a timezone was supplied." - changed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dawn_utc / descriptionPrevious value: -"Dawn (Sun ascending through the depth) in ISO 8601 UTC, or null if it does not occur."New value: +"Dawn (Sun ascending through the depth) in ISO 8601 UTC, or null if it does not occur. This is the morning after the cycle's set, ending the night that begins at the dusk beside it — a day later than the cycle's rise, not the dawn before it." - changed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dusk_local / descriptionPrevious value: -"Dusk in observer-local time, present only when a timezone was supplied."New value: +"Dusk in observer-local time — the evening of the cycle's set — present only when a timezone was supplied." - changed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dusk_utc / descriptionPrevious value: -"Dusk (Sun descending through the depth) in ISO 8601 UTC, or null if it does not occur."New value: +"Dusk (Sun descending through the depth) in ISO 8601 UTC, or null if it does not occur. This is the evening of the cycle's set." - changed
Output schema / properties / events / items / properties / twilight / properties / nautical / descriptionPrevious value: -"Nautical twilight (Sun at −12°) dawn and dusk."New value: +"Nautical twilight (Sun at −12°): dusk and the following dawn." - changed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dawn_local / descriptionPrevious value: -"Dawn in observer-local time, present only when a timezone was supplied."New value: +"Dawn in observer-local time — the morning after the cycle's set — present only when a timezone was supplied." - changed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dawn_utc / descriptionPrevious value: -"Dawn (Sun ascending through the depth) in ISO 8601 UTC, or null if it does not occur."New value: +"Dawn (Sun ascending through the depth) in ISO 8601 UTC, or null if it does not occur. This is the morning after the cycle's set, ending the night that begins at the dusk beside it — a day later than the cycle's rise, not the dawn before it." - changed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dusk_local / descriptionPrevious value: -"Dusk in observer-local time, present only when a timezone was supplied."New value: +"Dusk in observer-local time — the evening of the cycle's set — present only when a timezone was supplied." - changed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dusk_utc / descriptionPrevious value: -"Dusk (Sun descending through the depth) in ISO 8601 UTC, or null if it does not occur."New value: +"Dusk (Sun descending through the depth) in ISO 8601 UTC, or null if it does not occur. This is the evening of the cycle's set."
- Changed
astronomy_get_sky_position4 fields changed- changed
Input schema / properties / star / descriptionPrevious value: -"Named bright star to locate (common name or Bayer designation, e.g. \"Sirius\", \"Alpha Centauri\"). Takes precedence over `body`."New value: +"Named star to locate, from a bundled catalog of 32 stars — about 30 of the brightest naked-eye stars plus Polaris, not an arbitrary star. Accepts a common name or Bayer designation, with the Greek letter spelled out or as a symbol and the constellation as its genitive or IAU abbreviation (e.g. \"Sirius\", \"Alpha Centauri\", \"α CMa\"). A name outside the catalog fails with the full list of catalog stars. Takes precedence over `body`." - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "body", - "time_utc", - "equatorial", - "horizontal", - "ecliptic", - "magnitude", - "angular_diameter_arcsec", - "phase_angle_degrees", - "illuminated_fraction", - "constellation" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "body", + "time_utc", + "equatorial", + "horizontal", + "ecliptic", + "magnitude", + "angular_diameter_arcsec", + "phase_angle_degrees", + "illuminated_fraction", + "sun_elongation_degrees", + "constellation" + ] + }, + { + "required": [ + "error" + ] + } +] - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_time`: The `time` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. `star_not_found`: The `star` name is not present in the bundled bright-star catalog. `body_required`: Neither a `body` nor a `star` was supplied. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_time`: The `time` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. `star_not_found`: The `star` name is not present in the bundled bright-star catalog. The error lists every catalog star, in the message and as `catalog_stars`. `body_required`: Neither a `body` nor a `star` was supplied. Other values are possible when a failure originates below the handler." - added
Output schema / properties / sun_elongation_degreesAdded value: +{ + "description": "Angular distance from the Sun in degrees [0,180], seen from Earth's center. A body within about 15° of the Sun is lost in its glare. 0 for the Sun itself.", + "type": "number" +}
- Changed
astronomy_list_visible3 fields changed- added
Output schema / properties / bodies / items / properties / sun_elongation_degreesAdded value: +{ + "description": "Angular distance from the Sun in degrees [0,180], seen from Earth's center. A body within about 15° of the Sun is lost in its glare. 0 for the Sun itself.", + "type": "number" +} - changed
Output schema / properties / bodies / items / properties / visibility_note / descriptionPrevious value: -"Server-computed one-line headline from real values, e.g. \"Venus, mag -4.1, 12° above the WSW horizon — very bright\"."New value: +"Server-computed one-line headline from real values, e.g. \"Venus, mag -4.1, 12° above the WSW horizon — very bright\". It states when the conditions hide a body: \"daylight, not naked-eye visible\" when the Sun is up, \"N° from the Sun, lost in glare\" within 15° of the Sun, and \"civil twilight, sky still bright\" in civil twilight. The Moon and a negative-magnitude Venus take no daylight or twilight caveat, being visible in a blue sky; the Sun takes none." - changed
Output schema / properties / bodies / items / requiredPrevious value: -[ - "body", - "time_utc", - "equatorial", - "horizontal", - "ecliptic", - "magnitude", - "angular_diameter_arcsec", - "phase_angle_degrees", - "illuminated_fraction", - "constellation", - "rank", - "visibility_note" -]New value: +[ + "body", + "time_utc", + "equatorial", + "horizontal", + "ecliptic", + "magnitude", + "angular_diameter_arcsec", + "phase_angle_degrees", + "illuminated_fraction", + "sun_elongation_degrees", + "constellation", + "rank", + "visibility_note" +]
2 tool updates
- Changed
astronomy_get_ephemeris4 fields changed- changed
Input schema / properties / designation / descriptionPrevious value: -"JPL Horizons target, passed verbatim — use a form that resolves to one record. Numbered asteroid: trailing-semicolon record lookup, e.g. \"433;\" (Eros), \"1;\" (Ceres). Periodic comet: DES + closest-apparition flag, e.g. \"DES=1P;CAP\" (Halley), \"DES=2P;CAP\" (Encke). Spacecraft: negative SPK-ID, e.g. \"-48\" (Hubble). A bare name like \"433 Eros\" or \"1P/Halley\" fails. Look up designations at ssd.jpl.nasa.gov/tools/sbdb_lookup.html."New value: +"JPL Horizons target, passed verbatim — use a form that resolves to one record. Numbered asteroid: trailing-semicolon record lookup, e.g. \"433;\" (Eros), \"1;\" (Ceres). Periodic comet: DES + closest-apparition flag, e.g. \"DES=1P;CAP\" (Halley), \"DES=2P;CAP\" (Encke). Spacecraft: negative SPK-ID, e.g. \"-48\" (Hubble). A bare name like \"433 Eros\" (no match) or \"1P/Halley\" (several records) is rejected, but one matching a single object succeeds even when it is not the object meant — check `target_name` in the result. Look up designations at ssd.jpl.nasa.gov/tools/sbdb_lookup.html." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_time`: The start or stop timestamp is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `invalid_time_range`: The resolved stop instant is at or before the resolved start instant. `incomplete_observer`: Exactly one of latitude and longitude was supplied. `invalid_step`: The step is not a positive count followed by a unit of m, h, d, mo, or y. `body_not_found`: JPL Horizons has no match for the designation, or the designation is ambiguous (a bare comet name matches multiple apparition records). `horizons_unavailable`: The JPL Horizons API failed after retries. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_time`: The start or stop timestamp is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `invalid_time_range`: The resolved stop instant is at or before the resolved start instant. `incomplete_observer`: Exactly one of latitude and longitude was supplied. `invalid_step`: The step is not a positive count followed by a unit of m, h, d, mo, or y. `time_out_of_range`: The requested span falls outside the target's Horizons data span. The message names the bound Horizons reported, e.g. after A.D. 2599-DEC-31 for Mars. `body_not_found`: JPL Horizons has no match for the designation, or the designation is ambiguous (a bare comet name matches multiple apparition records). `horizons_unavailable`: The JPL Horizons API failed after retries. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_time", - "invalid_time_range", - "incomplete_observer", - "invalid_step", - "body_not_found", - "horizons_unavailable" -]New value: +[ + "invalid_time", + "invalid_time_range", + "incomplete_observer", + "invalid_step", + "time_out_of_range", + "body_not_found", + "horizons_unavailable" +] - added
Output schema / properties / target_nameAdded value: +{ + "description": "The object JPL Horizons resolved the designation to, from its 'Target body name' header — compare it with the intended object, since a bare name can resolve to a different one. Absent when Horizons' response names no target.", + "type": "string" +}
- Changed
astronomy_get_satellite_passes1 field changed- changed
Input schema / properties / name / descriptionPrevious value: -"Satellite name to resolve against CelesTrak, e.g. \"ISS (ZARYA)\". Matched as a case-insensitive substring of the catalog name, so give the fullest name you have — a short one matches many objects and is rejected as ambiguous. Mutually exclusive with `norad_id` — supply exactly one."New value: +"Satellite name to resolve, e.g. \"ISS (ZARYA)\". The common names ISS, International Space Station, Hubble, Hubble Space Telescope, HST, Tiangong, CSS, and Chinese Space Station resolve directly to their catalog numbers, ignoring case and surrounding whitespace. Any other name is matched against CelesTrak as a case-insensitive substring of the catalog name, so give the fullest name you have — a short one matches many objects and is rejected as ambiguous. Mutually exclusive with `norad_id` — supply exactly one."
1 tool update
- Changed
astronomy_find_events10 fields changed- changed
Input schema / properties / latitude / descriptionPrevious value: -"Observer latitude in decimal degrees — required for solar_eclipse to get local circumstances, ignored by every other event."New value: +"Observer latitude in decimal degrees, supplied together with longitude. Optional for solar_eclipse and lunar_eclipse, where it adds local circumstances; omit both for a global solar search. Ignored by every other event." - changed
Input schema / properties / longitude / descriptionPrevious value: -"Observer longitude in decimal degrees — required for solar_eclipse, ignored by every other event."New value: +"Observer longitude in decimal degrees, supplied together with latitude. Optional for solar_eclipse and lunar_eclipse; ignored by every other event." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `observer_required`: A solar_eclipse event was requested without observer latitude/longitude. `body_required`: A body-relative event was requested without a target body. `body_not_supported`: The body has no such event — opposition for the Sun, Moon, Earth, or an inner planet; conjunction for the Sun, Moon, or Earth; max_elongation for anything but mercury or venus; perigee_apogee for the Sun. `invalid_time`: The `start` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested start instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `incomplete_observer`: A solar_eclipse or lunar_eclipse was requested with only one of latitude and longitude. `body_required`: A body-relative event was requested without a target body. `body_not_supported`: The body has no such event — opposition for the Sun, Moon, Earth, or an inner planet; conjunction for the Sun, Moon, or Earth; max_elongation for anything but mercury or venus; perigee_apogee for the Sun. `invalid_time`: The `start` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested start instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "observer_required", - "body_required", - "body_not_supported", - "invalid_time", - "time_out_of_range", - "invalid_timezone" -]New value: +[ + "incomplete_observer", + "body_required", + "body_not_supported", + "invalid_time", + "time_out_of_range", + "invalid_timezone" +] - added
Output schema / properties / events / items / properties / contact_altitudes_degreesAdded value: +{ + "additionalProperties": { + "type": [ + "number", + "null" + ] + }, + "description": "Apparent altitude in degrees of the eclipsed body (the Sun for solar_eclipse, the Moon for lunar_eclipse) above the observer's horizon at each contact, keyed by bare phase name: partial_begin, total_begin, peak, total_end, partial_end, plus penumbral_begin and penumbral_end for a lunar eclipse. Negative means below the horizon; null marks a phase this eclipse does not reach. Present only when latitude/longitude are supplied.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Output schema / properties / events / items / properties / contacts / descriptionPrevious value: -"Eclipse contact times in ISO 8601 UTC keyed by phase (e.g. partial_begin_utc, peak_utc); a phase that does not occur is null."New value: +"Eclipse contact times in ISO 8601 UTC keyed by phase (e.g. partial_begin_utc, peak_utc); a phase that does not occur is null. A global solar eclipse carries peak_utc only." - changed
Output schema / properties / events / items / properties / local_visible / descriptionPrevious value: -"True when the eclipsed Sun is above the observer's horizon at peak. Present for solar eclipses only — lunar eclipses are geocentric and report no local visibility."New value: +"True when the eclipsed body — the Sun for solar_eclipse, the Moon for lunar_eclipse — is above the observer's horizon at any contact. Present only when latitude/longitude are supplied. A solar result with an observer is always true, because the local search returns only eclipses with the Sun up at first or last contact; contact_altitudes_degrees tells an eclipse at sunrise or sunset from one at midday." - added
Output schema / properties / events / items / properties / peak_latitude_degreesAdded value: +{ + "description": "Geographic latitude in degrees where a total or annular solar eclipse is greatest. Present for a solar_eclipse searched without an observer; absent for a partial eclipse, whose shadow axis misses Earth.", + "type": "number" +} - added
Output schema / properties / events / items / properties / peak_longitude_degreesAdded value: +{ + "description": "Geographic longitude in degrees where a total or annular solar eclipse is greatest. Present for a solar_eclipse searched without an observer; absent for a partial eclipse.", + "type": "number" +} - added
Output schema / properties / noticeAdded value: +{ + "description": "Why the list is shorter than the requested count: the search reached the end of the supported span (2100). Absent when every requested occurrence came back.", + "type": "string" +}
5 tool updates
- Changed
astronomy_find_events4 fields changed- removed
Output schema / properties / events / items / properties / contacts / additionalProperties / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / contacts / additionalProperties / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / obscuration / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / obscuration / typeAdded value: +[ + "number", + "null" +]
- Changed
astronomy_get_ephemeris2 fields changed- removed
Output schema / properties / points / items / properties / magnitude / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / points / items / properties / magnitude / typeAdded value: +[ + "number", + "null" +]
- Changed
astronomy_get_rise_set32 fields changed- removed
Output schema / properties / events / items / properties / rise_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / rise_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / set_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / set_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / transit_altitude_degrees / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / transit_altitude_degrees / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / events / items / properties / transit_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / transit_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dawn_local / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dawn_local / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dawn_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dawn_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dusk_local / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dusk_local / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dusk_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / astronomical / properties / dusk_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dawn_local / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dawn_local / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dawn_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dawn_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dusk_local / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dusk_local / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dusk_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / civil / properties / dusk_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dawn_local / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dawn_local / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dawn_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dawn_utc / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dusk_local / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dusk_local / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dusk_utc / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / twilight / properties / nautical / properties / dusk_utc / typeAdded value: +[ + "string", + "null" +]
- Changed
astronomy_get_sky_position8 fields changed- removed
Output schema / properties / angular_diameter_arcsec / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / angular_diameter_arcsec / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / illuminated_fraction / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / illuminated_fraction / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / magnitude / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / magnitude / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / phase_angle_degrees / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / phase_angle_degrees / typeAdded value: +[ + "number", + "null" +]
- Changed
astronomy_list_visible8 fields changed- removed
Output schema / properties / bodies / items / properties / angular_diameter_arcsec / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / bodies / items / properties / angular_diameter_arcsec / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / bodies / items / properties / illuminated_fraction / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / bodies / items / properties / illuminated_fraction / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / bodies / items / properties / magnitude / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / bodies / items / properties / magnitude / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / bodies / items / properties / phase_angle_degrees / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / bodies / items / properties / phase_angle_degrees / typeAdded value: +[ + "number", + "null" +]
7 tool updates
- Changed
astronomy_find_events6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "events", + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `observer_required`: A solar_eclipse event was requested without observer latitude/longitude. `body_required`: A body-relative event was requested without a target body. `body_not_supported`: The body has no such event — opposition for the Sun, Moon, Earth, or an inner planet; conjunction for the Sun, Moon, or Earth; max_elongation for anything but mercury or venus; perigee_apogee for the Sun. `invalid_time`: The `start` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested start instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler.", + "examples": [ + "observer_required", + "body_required", + "body_not_supported", + "invalid_time", + "time_out_of_range", + "invalid_timezone" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "events", - "totalCount" -]
- Changed
astronomy_get_ephemeris6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "designation", + "points", + "truncated", + "shown", + "cap" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_time`: The start or stop timestamp is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `invalid_time_range`: The resolved stop instant is at or before the resolved start instant. `incomplete_observer`: Exactly one of latitude and longitude was supplied. `invalid_step`: The step is not a positive count followed by a unit of m, h, d, mo, or y. `body_not_found`: JPL Horizons has no match for the designation, or the designation is ambiguous (a bare comet name matches multiple apparition records). `horizons_unavailable`: The JPL Horizons API failed after retries. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_time", + "invalid_time_range", + "incomplete_observer", + "invalid_step", + "body_not_found", + "horizons_unavailable" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "designation", - "points", - "truncated", - "shown", - "cap" -]
- Changed
astronomy_get_moon_phase6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "time_utc", + "phase_angle_degrees", + "illuminated_fraction", + "phase_name", + "age_days", + "next_quarters" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_time`: The `time` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_time", + "time_out_of_range", + "invalid_timezone" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "time_utc", - "phase_angle_degrees", - "illuminated_fraction", - "phase_name", - "age_days", - "next_quarters" -]
- Changed
astronomy_get_rise_set6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "body", + "events", + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_time`: The `start` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested start instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_time", + "time_out_of_range", + "invalid_timezone" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "body", - "events", - "totalCount" -]
- Changed
astronomy_get_satellite_passes6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "norad_id", + "passes", + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_time`: The start timestamp is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The start instant is outside the SGP4 high-accuracy span (≈1900–2100), or more than about a month from the epoch of the current element set — checked on the epoch distance itself, since SGP4 keeps returning positions well past the point where the mean elements describe the orbit. `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. `invalid_target`: Neither `norad_id` nor `name` was supplied, or both were. `tle_not_found`: CelesTrak has no current element set for the NORAD ID. `satellite_name_not_found`: No current CelesTrak object has a name containing the `name` value. `ambiguous_satellite_name`: The `name` value matches more than one current object and none of them carries it as their whole name. The error names the match count and lists the matching objects with their catalog numbers, capped when there are more than the list holds. A capped list carries a hint leading with narrowing instead of with the list, since the wanted object need not be among the ones shown. `object_decayed`: A current element set will not propagate to a window near its own epoch — the signature of an object that has reentered. `celestrak_unavailable`: The element-set fetch failed after retries, or returned a body that is not JSON at all. `malformed_element_set`: CelesTrak answered with parsable JSON whose GP record does not carry the fields an OMM element set requires — a permanent property of that record, not the transient outage celestrak_unavailable covers. The same request returns the same record, so retrying it can only fail again. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_time", + "time_out_of_range", + "invalid_timezone", + "invalid_target", + "tle_not_found", + "satellite_name_not_found", + "ambiguous_satellite_name", + "object_decayed", + "celestrak_unavailable", + "malformed_element_set" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "norad_id", - "passes", - "totalCount" -]
- Changed
astronomy_get_sky_position6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "body", + "time_utc", + "equatorial", + "horizontal", + "ecliptic", + "magnitude", + "angular_diameter_arcsec", + "phase_angle_degrees", + "illuminated_fraction", + "constellation" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_time`: The `time` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. `star_not_found`: The `star` name is not present in the bundled bright-star catalog. `body_required`: Neither a `body` nor a `star` was supplied. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_time", + "time_out_of_range", + "invalid_timezone", + "star_not_found", + "body_required" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "body", - "time_utc", - "equatorial", - "horizontal", - "ecliptic", - "magnitude", - "angular_diameter_arcsec", - "phase_angle_degrees", - "illuminated_fraction", - "constellation" -]
- Changed
astronomy_list_visible6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "sky_condition", + "sun_altitude_degrees", + "total_count", + "bodies" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_time`: The `time` value is not a parseable ISO 8601 instant, or names a calendar date that does not exist (e.g. 2026-02-30). `time_out_of_range`: The requested instant is outside the engine's high-accuracy span (≈1900–2100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_time", + "time_out_of_range", + "invalid_timezone" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "sky_condition", - "sun_altitude_degrees", - "total_count", - "bodies" -]
7 tool updates
- Changed
astronomy_find_events1 field changed- changed
Input schema / properties / start / descriptionPrevious value: -"Search start as an ISO 8601 UTC string, e.g. \"2024-01-01T00:00:00Z\". Defaults to now."New value: +"Search start as an ISO 8601 UTC string, e.g. \"2024-01-01T00:00:00Z\". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process."
- Changed
astronomy_get_ephemeris2 fields changed- changed
Input schema / properties / start / descriptionPrevious value: -"Ephemeris start as an ISO 8601 UTC string, e.g. \"2024-01-01T00:00:00Z\". Defaults to now."New value: +"Ephemeris start as an ISO 8601 UTC string, e.g. \"2024-01-01T00:00:00Z\". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process." - changed
Input schema / properties / stop / descriptionPrevious value: -"Ephemeris stop as an ISO 8601 UTC string, and must be later than start. Defaults to 24 hours after start."New value: +"Ephemeris stop as an ISO 8601 UTC string, and must be later than start. Defaults to 24 hours after start. A value with no zone designator is read as UTC, not the local zone of the server process."
- Changed
astronomy_get_moon_phase1 field changed- changed
Input schema / properties / time / descriptionPrevious value: -"Instant to evaluate as an ISO 8601 UTC string, e.g. \"2024-12-15T00:00:00Z\". Defaults to now."New value: +"Instant to evaluate as an ISO 8601 UTC string, e.g. \"2024-12-15T00:00:00Z\". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process."
- Changed
astronomy_get_rise_set2 fields changed- changed
Input schema / properties / start / descriptionPrevious value: -"Search start as an ISO 8601 UTC string, e.g. \"2024-06-21T00:00:00Z\". Defaults to now."New value: +"Search start as an ISO 8601 UTC string, e.g. \"2024-06-21T00:00:00Z\". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process." - changed
Output schema / properties / events / items / properties / rise_utc / descriptionPrevious value: -"Rise time in ISO 8601 UTC, or null when the body does not rise in this cycle (e.g. circumpolar)."New value: +"Rise time in ISO 8601 UTC, or null when the body does not rise in this cycle — because it is circumpolar, or because it was already above the horizon at the search start, whose rise precedes the search. The accompanying note says which."
- Changed
astronomy_get_satellite_passes1 field changed- changed
Input schema / properties / start / descriptionPrevious value: -"Search start as an ISO 8601 UTC string, within about a month of the current element set's epoch — for a tracked object that epoch is hours old, so in practice within about a month of today. A start further out is rejected rather than answered from elements that no longer describe the orbit. Defaults to now."New value: +"Search start as an ISO 8601 UTC string, within about a month of the current element set's epoch — for a tracked object that epoch is hours old, so in practice within about a month of today. A start further out is rejected rather than answered from elements that no longer describe the orbit. Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process."
- Changed
astronomy_get_sky_position2 fields changed- changed
Input schema / properties / time / descriptionPrevious value: -"Instant of observation as an ISO 8601 UTC string, e.g. \"2024-04-08T18:00:00Z\". Defaults to now."New value: +"Instant of observation as an ISO 8601 UTC string, e.g. \"2024-04-08T18:00:00Z\". Defaults to now. A value with no zone designator is read as UTC, not the local zone of the server process." - added
Output schema / properties / body_metadataAdded value: +{ + "additionalProperties": false, + "description": "The body card also served at astronomy://body/{body}, copied here so a client without resource support can reach it. Present for the ten solar-system bodies; absent for a catalog star, which has no card.", + "properties": { + "mean_radius_km": { + "description": "Mean radius in kilometers, from IAU/NASA fact sheets.", + "type": "number" + }, + "naked_eye": { + "description": "True when the body is typically visible to the naked eye.", + "type": "boolean" + }, + "type": { + "description": "Classification of the body.", + "enum": [ + "star", + "planet", + "moon", + "dwarf" + ], + "type": "string" + } + }, + "required": [ + "type", + "mean_radius_km", + "naked_eye" + ], + "type": "object" +}
- Changed
astronomy_list_visible1 field changed- changed
Input schema / properties / time / descriptionPrevious value: -"Evaluation instant as an ISO 8601 UTC string, e.g. \"2024-08-12T05:00:00Z\". Defaults to now. A single instant, not a window."New value: +"Evaluation instant as an ISO 8601 UTC string, e.g. \"2024-08-12T05:00:00Z\". Defaults to now. A single instant, not a window. A value with no zone designator is read as UTC, not the local zone of the server process."
1 tool update
- Changed
astronomy_get_satellite_passes1 field changed- changed
Input schema / properties / start / descriptionPrevious value: -"Search start as an ISO 8601 UTC string, within about a month of today — the current element set cannot be propagated further. Defaults to now."New value: +"Search start as an ISO 8601 UTC string, within about a month of the current element set's epoch — for a tracked object that epoch is hours old, so in practice within about a month of today. A start further out is rejected rather than answered from elements that no longer describe the orbit. Defaults to now."
1 tool update
- Changed
astronomy_get_satellite_passes6 fields changed- added
Input schema / oneOfAdded value: +[ + { + "not": { + "required": [ + "name" + ] + }, + "required": [ + "norad_id" + ], + "type": "object" + }, + { + "not": { + "required": [ + "norad_id" + ] + }, + "required": [ + "name" + ], + "type": "object" + } +] - added
Input schema / properties / nameAdded value: +{ + "description": "Satellite name to resolve against CelesTrak, e.g. \"ISS (ZARYA)\". Matched as a case-insensitive substring of the catalog name, so give the fullest name you have — a short one matches many objects and is rejected as ambiguous. Mutually exclusive with `norad_id` — supply exactly one.", + "type": "string" +} - changed
Input schema / properties / norad_id / descriptionPrevious value: -"NORAD catalog number of the satellite, e.g. 25544 for the ISS. Found at celestrak.org or heavens-above.com."New value: +"NORAD catalog number of the satellite, e.g. 25544 for the ISS. Found at celestrak.org or heavens-above.com. Mutually exclusive with `name` — supply exactly one." - changed
Input schema / requiredPrevious value: -[ - "norad_id", - "latitude", - "longitude" -]New value: +[ + "latitude", + "longitude" +] - added
Output schema / properties / resolved_from_nameAdded value: +{ + "description": "The name query that resolved this object. Present only when the request supplied `name` rather than `norad_id`.", + "type": "string" +} - changed
Output schema / properties / satellite_name / descriptionPrevious value: -"Satellite name from the TLE header, when present."New value: +"Satellite name as CelesTrak catalogs it (the element set's OBJECT_NAME)."
7 tool updates
- First observed
astronomy_find_events - First observed
astronomy_get_ephemeris - First observed
astronomy_get_moon_phase - First observed
astronomy_get_rise_set - First observed
astronomy_get_satellite_passes - First observed
astronomy_get_sky_position - First observed
astronomy_list_visible
Related MCP Connectors
Astronomy: sun, moon, planet, eclipse, twilight and star position calculations.
Elevation-corrected sun, moon, twilight, solar and tide data for any point on Earth
Birth charts, transits, moon phases and more from precise astronomical calculations. Natal Compass.
Observatory-grade Indian astronomy, years -5000..+5000: positions, eclipses, panchang date search.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides 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 gradedqualityBmaintenanceProvides solar eclipse predictions, local eclipse circumstances, Moon phases, and seasons from the US Naval Observatory's Astronomical Applications API.122 npmMIT
- AlicenseAqualityAmaintenanceCalculate the altitude, rise, and set times of celestial objects (Sun, Moon, planets, stars, and deep-space objects) for any location on Earth.15MIT
- FlicenseAqualityDmaintenanceProvides astronomical calculations using the Swiss Ephemeris library, including planetary positions, houses, chart points, and asteroids for any date and location.49-
Glama MCP Gateway
Add one secure layer between your agents and this server.