MCP 服务器

astronomy-mcp-server

io.github.cyanheads/astronomy-mcp-server
科学与工程 公开且可连接 MCP 2025-11-25

此 MCP 可以做什么

Computes offline astronomy positions, visibility, rise and set times, satellite passes, ephemerides, moon phases, eclipses, and seasonal events.

astronomy_find_events
astronomy-mcp-server: find sky events
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.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['event'], 'properties': {'body': {'enum': ['sun', 'moon', 'mercury', 'venus', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune', 'pluto', 'earth'], 'type': 'string', 'description': 'Target body â\x80\x94 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': {'type': 'integer', 'default': 1, 'maximum': 20, 'minimum': 1, 'description': 'Number of forward occurrences to return. Default 1, max 20.'}, 'event': {'enum': ['solar_eclipse', 'lunar_eclipse', 'equinox', 'solstice', 'moon_quarter', 'opposition', 'conjunction', 'max_elongation', 'perigee_apogee'], 'type': 'string', 'description': 'Which class of event to search for.'}, 'start': {'type': 'string', 'description': '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': {'type': 'number', 'maximum': 90, 'minimum': -90, 'description': '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': {'type': 'string', 'description': 'IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only.'}, 'elevation': {'type': 'number', 'default': 0, 'description': 'Observer elevation in meters above sea level. Default 0.'}, 'longitude': {'type': 'number', 'maximum': 180, 'minimum': -180, 'description': 'Observer longitude in decimal degrees, supplied together with latitude. Optional for solar_eclipse and lunar_eclipse; ignored by every other event.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'not': {'required': ['error']}, 'required': ['events', 'totalCount']}, {'required': ['error']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', 'examples': ['incomplete_observer', 'body_required', 'body_not_supported', 'invalid_time', 'time_out_of_range', 'invalid_timezone'], 'description': "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 â\x80\x94 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 (â\x89\x881900â\x80\x932100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler."}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'events': {'type': 'array', 'items': {'type': 'object', 'required': ['event', 'time_utc'], 'properties': {'body': {'type': 'string', 'description': 'The target body. Present for opposition/conjunction/max_elongation/perigee_apogee.'}, 'kind': {'type': 'string', 'description': 'Eclipse classification: "penumbral", "partial", "annular", or "total". Present for eclipses.'}, 'event': {'enum': ['solar_eclipse', 'lunar_eclipse', 'equinox', 'solstice', 'moon_quarter', 'opposition', 'conjunction', 'max_elongation', 'perigee_apogee'], 'type': 'string', 'description': 'The event class this record belongs to.'}, 'which': {'enum': ['march', 'september', 'june', 'december'], 'type': 'string', 'description': 'Which equinox or solstice. Present for equinox/solstice events.'}, 'quarter': {'enum': ['new', 'first_quarter', 'full', 'last_quarter'], 'type': 'string', 'description': 'Which lunar quarter. Present for moon_quarter events.'}, 'contacts': {'type': 'object', 'description': '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.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {'type': ['string', 'null']}}, 'time_utc': {'type': 'string', 'description': 'Time of the event (peak, for eclipses) in ISO 8601 UTC.'}, 'apsis_kind': {'enum': ['perigee', 'apogee', 'perihelion', 'aphelion'], 'type': 'string', 'description': 'Apsis classification. Present for perigee_apogee events.'}, 'time_local': {'type': 'string', 'description': 'Event time in observer-local time, present only when a timezone was supplied.'}, 'visibility': {'enum': ['morning', 'evening'], 'type': 'string', 'description': 'Whether the apparition is in the morning or evening sky. Present for max_elongation.'}, 'distance_au': {'type': 'number', 'description': 'Center-to-center distance at the apsis in astronomical units. Present for perigee_apogee.'}, 'distance_km': {'type': 'number', 'description': 'Center-to-center distance at the apsis in kilometers. Present for perigee_apogee.'}, 'obscuration': {'type': ['number', 'null'], 'description': 'Peak fraction of the disc obscured, 0 to 1. Null/absent when undefined for a global partial solar eclipse.'}, 'local_visible': {'type': 'boolean', 'description': "True when the eclipsed body â\x80\x94 the Sun for solar_eclipse, the Moon for lunar_eclipse â\x80\x94 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."}, 'conjunction_kind': {'enum': ['inferior', 'superior'], 'type': 'string', 'description': 'Whether the planet passes between Earth and the Sun (inferior) or behind the Sun (superior). Present only for mercury and venus conjunctions, the two bodies that reach both.'}, 'elongation_degrees': {'type': 'number', 'description': 'Greatest-elongation angle in degrees from the Sun. Present for max_elongation.'}, 'peak_latitude_degrees': {'type': 'number', '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.'}, 'peak_longitude_degrees': {'type': 'number', '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.'}, 'contact_altitudes_degrees': {'type': 'object', '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'}, 'additionalProperties': {'type': ['number', 'null']}}}, 'description': 'One event occurrence; which detail fields are present depends on the event class.', 'additionalProperties': False}, 'description': 'The next occurrences of the requested event class, in chronological order.'}, 'notice': {'type': 'string', '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.'}, 'totalCount': {'type': 'number', 'description': 'Number of event occurrences returned.'}}, 'additionalProperties': False}
astronomy_get_ephemeris
astronomy-mcp-server: get small-body ephemeris
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.
只读 可访问外部资源 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['designation'], 'properties': {'step': {'type': 'string', 'default': '1h', 'description': '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".'}, 'stop': {'type': 'string', 'description': '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': {'type': 'string', 'description': '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': {'type': 'number', 'maximum': 90, 'minimum': -90, 'description': 'Observer latitude in decimal degrees â\x80\x94 supply together with longitude for topocentric coordinates and alt/az. Supplying one without the other is rejected.'}, 'elevation': {'type': 'number', 'default': 0, 'description': 'Observer elevation in meters above sea level. Default 0.'}, 'longitude': {'type': 'number', 'maximum': 180, 'minimum': -180, 'description': 'Observer longitude in decimal degrees. Supply together with latitude; one without the other is rejected.'}, 'designation': {'type': 'string', 'minLength': 1, 'description': 'JPL Horizons target, passed verbatim â\x80\x94 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 â\x80\x94 check `target_name` in the result. Look up designations at ssd.jpl.nasa.gov/tools/sbdb_lookup.html.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'not': {'required': ['error']}, 'required': ['designation', 'points', 'truncated', 'shown', 'cap']}, {'required': ['error']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'cap': {'type': 'number', 'description': 'The inline row cap that was applied.'}, 'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', 'examples': ['invalid_time', 'invalid_time_range', 'incomplete_observer', 'invalid_step', 'time_out_of_range', 'body_not_found', 'horizons_unavailable'], '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. `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."}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'shown': {'type': 'number', 'description': 'Number of ephemeris rows returned.'}, 'notice': {'type': 'string', 'description': 'Caveats on the returned series â\x80\x94 how to retrieve rows omitted by the cap, and whether any rows were dropped. Absent when the whole span came back intact.'}, 'points': {'type': 'array', 'items': {'type': 'object', 'required': ['time_utc', 'ra_hours', 'dec_degrees', 'distance_au', 'magnitude'], 'properties': {'ra_hours': {'type': 'number', 'description': 'Right ascension in sidereal hours [0,24).'}, 'time_utc': {'type': 'string', 'description': 'Step instant in ISO 8601 UTC.'}, 'magnitude': {'type': ['number', 'null'], 'description': 'Apparent magnitude, or null when Horizons omits it for this body.'}, 'dec_degrees': {'type': 'number', 'description': 'Declination in degrees [-90,90].'}, 'distance_au': {'type': 'number', 'description': 'Observer-to-body distance in astronomical units.'}, 'azimuth_degrees': {'type': 'number', 'description': 'Azimuth in degrees (0=N, 90=E, 180=S, 270=W). Present only when an observer was supplied.'}, 'altitude_degrees': {'type': 'number', 'description': 'Refraction-corrected altitude in degrees. Present only when an observer was supplied.'}}, 'description': 'One ephemeris step: position and, with an observer, alt/az.', 'additionalProperties': False}, 'description': 'Time-series of positions, one per step, in chronological order.'}, 'dropped': {'type': 'number', 'description': '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': {'type': 'boolean', 'description': 'True when Horizons returned more rows than the inline cap.'}, 'designation': {'type': 'string', 'description': 'The body designation echoed from the request.'}, 'target_name': {'type': 'string', 'description': "The object JPL Horizons resolved the designation to, from its 'Target body name' header â\x80\x94 compare it with the intended object, since a bare name can resolve to a different one. Absent when Horizons' response names no target."}}, 'additionalProperties': False}
astronomy_get_moon_phase
astronomy-mcp-server: get moon phase
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.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'time': {'type': 'string', 'description': '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': {'type': 'string', 'description': 'IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'not': {'required': ['error']}, 'required': ['time_utc', 'phase_longitude_degrees', 'illuminated_fraction', 'phase_name', 'age_days', 'next_quarters']}, {'required': ['error']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', 'examples': ['invalid_time', 'time_out_of_range', 'invalid_timezone'], '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 (â\x89\x881900â\x80\x932100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler."}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'age_days': {'type': 'number', 'description': 'Synodic age in days since the previous new moon.'}, 'time_utc': {'type': 'string', 'description': 'The instant the phase was computed for, in ISO 8601 UTC.'}, 'phase_name': {'type': 'string', 'description': 'Human-readable phase name (New Moon, Waxing Crescent, First Quarter, â\x80¦, Waning Crescent).'}, 'time_local': {'type': 'string', 'description': 'The same instant in the observer-local timezone with offset, present only when a timezone was supplied.'}, 'next_quarters': {'type': 'array', 'items': {'type': 'object', 'required': ['quarter', 'time_utc'], 'properties': {'quarter': {'enum': ['new', 'first_quarter', 'full', 'last_quarter'], 'type': 'string', 'description': 'Which quarter phase this entry is.'}, 'time_utc': {'type': 'string', 'description': 'Time of the quarter phase in ISO 8601 UTC.'}, 'time_local': {'type': 'string', 'description': 'Time of the quarter phase in the observer-local timezone, present only when a timezone was supplied.'}}, 'description': 'A single lunar quarter phase with its timestamp.', 'additionalProperties': False}, 'description': 'The next four lunar quarter phases (new/first/full/last) in chronological order.'}, 'illuminated_fraction': {'type': 'number', 'description': 'Fraction of the lunar disc illuminated, 0 to 1.'}, 'phase_longitude_degrees': {'type': 'number', '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â\x80\x93bodyâ\x80\x93observer phase angle astronomy_get_sky_position reports as phase_angle_degrees, which reads 0 at full moon."}}, 'additionalProperties': False}
astronomy_get_rise_set
astronomy-mcp-server: get rise/set times
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.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['body', 'latitude', 'longitude'], 'properties': {'body': {'enum': ['sun', 'moon', 'mercury', 'venus', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune', 'pluto'], 'type': 'string', 'description': 'The body to compute rise/set for. Twilight is included only when this is "sun".'}, 'count': {'type': 'integer', 'default': 1, 'maximum': 31, 'minimum': 1, 'description': 'Number of forward rise/set cycles to return. Default 1, max 31.'}, 'start': {'type': 'string', 'description': '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': {'type': 'number', 'maximum': 90, 'minimum': -90, 'description': 'Observer latitude in decimal degrees, north positive.'}, 'timezone': {'type': 'string', 'description': 'IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only.'}, 'elevation': {'type': 'number', 'default': 0, 'description': 'Observer elevation in meters above sea level. Default 0.'}, 'longitude': {'type': 'number', 'maximum': 180, 'minimum': -180, 'description': 'Observer longitude in decimal degrees, east positive.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'not': {'required': ['error']}, 'required': ['body', 'events', 'totalCount']}, {'required': ['error']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'body': {'type': 'string', 'description': 'The body these rise/set cycles are for, echoed from the request.'}, 'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', 'examples': ['invalid_time', 'time_out_of_range', 'invalid_timezone'], '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 (â\x89\x881900â\x80\x932100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler."}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'events': {'type': 'array', 'items': {'type': 'object', 'required': ['rise_utc', 'set_utc', 'transit_utc', 'transit_altitude_degrees'], 'properties': {'note': {'type': 'string', 'description': 'Explanatory note when a rise or set is absent (e.g. "Circumpolar â\x80\x94 never sets at this latitude/date.").'}, 'set_utc': {'type': ['string', 'null'], 'description': 'Set time in ISO 8601 UTC, or null when the body does not set in this cycle.'}, 'rise_utc': {'type': ['string', 'null'], 'description': 'Rise time in ISO 8601 UTC, or null when the body does not rise in this cycle â\x80\x94 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.'}, 'twilight': {'type': 'object', 'required': ['civil', 'nautical', 'astronomical'], 'properties': {'civil': {'type': 'object', 'required': ['dawn_utc', 'dusk_utc'], 'properties': {'dawn_utc': {'type': ['string', 'null'], 'description': "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 â\x80\x94 a day later than the cycle's rise, not the dawn before it."}, 'dusk_utc': {'type': ['string', 'null'], 'description': "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."}, 'dawn_local': {'type': ['string', 'null'], 'description': "Dawn in observer-local time â\x80\x94 the morning after the cycle's set â\x80\x94 present only when a timezone was supplied."}, 'dusk_local': {'type': ['string', 'null'], 'description': "Dusk in observer-local time â\x80\x94 the evening of the cycle's set â\x80\x94 present only when a timezone was supplied."}}, 'description': 'Civil twilight (Sun at â\x88\x926°): dusk and the following dawn.', 'additionalProperties': False}, 'nautical': {'type': 'object', 'required': ['dawn_utc', 'dusk_utc'], 'properties': {'dawn_utc': {'type': ['string', 'null'], 'description': "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 â\x80\x94 a day later than the cycle's rise, not the dawn before it."}, 'dusk_utc': {'type': ['string', 'null'], 'description': "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."}, 'dawn_local': {'type': ['string', 'null'], 'description': "Dawn in observer-local time â\x80\x94 the morning after the cycle's set â\x80\x94 present only when a timezone was supplied."}, 'dusk_local': {'type': ['string', 'null'], 'description': "Dusk in observer-local time â\x80\x94 the evening of the cycle's set â\x80\x94 present only when a timezone was supplied."}}, 'description': 'Nautical twilight (Sun at â\x88\x9212°): dusk and the following dawn.', 'additionalProperties': False}, 'astronomical': {'type': 'object', 'required': ['dawn_utc', 'dusk_utc'], 'properties': {'dawn_utc': {'type': ['string', 'null'], 'description': "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 â\x80\x94 a day later than the cycle's rise, not the dawn before it."}, 'dusk_utc': {'type': ['string', 'null'], 'description': "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."}, 'dawn_local': {'type': ['string', 'null'], 'description': "Dawn in observer-local time â\x80\x94 the morning after the cycle's set â\x80\x94 present only when a timezone was supplied."}, 'dusk_local': {'type': ['string', 'null'], 'description': "Dusk in observer-local time â\x80\x94 the evening of the cycle's set â\x80\x94 present only when a timezone was supplied."}}, 'description': 'Astronomical twilight (Sun at â\x88\x9218°): dusk and the following dawn, bounding the dark-sky window.', 'additionalProperties': False}}, 'description': '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 â\x80\x94 start the search a day earlier to get it.', 'additionalProperties': False}, 'set_local': {'type': 'string', 'description': 'Set time in observer-local time, present only when a timezone was supplied.'}, 'rise_local': {'type': 'string', 'description': 'Rise time in observer-local time, present only when a timezone was supplied.'}, 'transit_utc': {'type': ['string', 'null'], 'description': 'Culmination (highest point) time in ISO 8601 UTC, or null when not found.'}, 'transit_local': {'type': 'string', 'description': 'Culmination time in observer-local time, present only when a timezone was supplied.'}, 'transit_altitude_degrees': {'type': ['number', 'null'], 'description': 'Maximum altitude in degrees at culmination, or null when not found.'}}, 'description': 'One rise/set/transit cycle, with twilight when the body is the Sun.', 'additionalProperties': False}, 'description': 'One entry per rise/set/transit cycle, searching forward from the start time.'}, 'totalCount': {'type': 'number', 'description': 'Number of rise/set cycles returned.'}}, 'additionalProperties': False}
astronomy_get_satellite_passes
astronomy-mcp-server: get satellite passes
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.
只读 可访问外部资源 幂等
输入模式
{'type': 'object', 'oneOf': [{'not': {'required': ['name']}, 'type': 'object', 'required': ['norad_id']}, {'not': {'required': ['norad_id']}, 'type': 'object', 'required': ['name']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['latitude', 'longitude'], 'properties': {'days': {'type': 'integer', 'default': 7, 'maximum': 10, 'minimum': 1, 'description': 'Number of days ahead to search for passes. Default 7, max 10.'}, 'name': {'type': 'string', 'description': '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 â\x80\x94 a short one matches many objects and is rejected as ambiguous. Mutually exclusive with `norad_id` â\x80\x94 supply exactly one.'}, 'start': {'type': 'string', 'description': "Search start as an ISO 8601 UTC string, within about a month of the current element set's epoch â\x80\x94 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': {'type': 'number', 'maximum': 90, 'minimum': -90, 'description': 'Observer latitude in decimal degrees, north positive.'}, 'norad_id': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'NORAD catalog number of the satellite, e.g. 25544 for the ISS. Found at celestrak.org or heavens-above.com. Mutually exclusive with `name` â\x80\x94 supply exactly one.', 'exclusiveMinimum': 0}, 'timezone': {'type': 'string', 'description': 'IANA timezone for localized pass times, e.g. "America/Los_Angeles". When omitted, output is UTC-only.'}, 'elevation': {'type': 'number', 'default': 0, 'description': 'Observer elevation in meters above sea level. Default 0.'}, 'longitude': {'type': 'number', 'maximum': 180, 'minimum': -180, 'description': 'Observer longitude in decimal degrees, east positive.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'not': {'required': ['error']}, 'required': ['norad_id', 'passes', 'totalCount']}, {'required': ['error']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', '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'], '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 (â\x89\x881900â\x80\x932100), or more than about a month from the epoch of the current element set â\x80\x94 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 â\x80\x94 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 â\x80\x94 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.'}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'passes': {'type': 'array', 'items': {'type': 'object', 'required': ['rise_utc', 'peak_utc', 'set_utc', 'peak_altitude_degrees', 'rise_azimuth_degrees', 'set_azimuth_degrees', 'peak_azimuth_degrees', 'duration_seconds', 'sunlit'], 'properties': {'sunlit': {'type': 'boolean', 'description': 'True when the satellite is in sunlight at peak â\x80\x94 a precondition for naked-eye visibility.'}, 'set_utc': {'type': 'string', 'description': 'Loss of signal (set below horizon) in ISO 8601 UTC.'}, 'peak_utc': {'type': 'string', 'description': 'Time of maximum elevation in ISO 8601 UTC.'}, 'rise_utc': {'type': 'string', 'description': 'Acquisition of signal (rise above horizon) in ISO 8601 UTC.'}, 'set_local': {'type': 'string', 'description': 'Set time in observer-local time, present only when a timezone was supplied.'}, 'peak_local': {'type': 'string', 'description': 'Peak time in observer-local time, present only when a timezone was supplied.'}, 'rise_local': {'type': 'string', 'description': 'Rise time in observer-local time, present only when a timezone was supplied.'}, 'duration_seconds': {'type': 'number', 'description': 'Pass duration from rise to set, in seconds.'}, 'set_azimuth_degrees': {'type': 'number', 'description': 'Azimuth at set, in degrees.'}, 'peak_azimuth_degrees': {'type': 'number', 'description': 'Azimuth at peak elevation, in degrees.'}, 'rise_azimuth_degrees': {'type': 'number', 'description': 'Azimuth at rise, in degrees (0=N, 90=E, 180=S, 270=W).'}, 'peak_altitude_degrees': {'type': 'number', 'description': 'Maximum elevation angle during the pass, in degrees.'}}, 'description': 'One visible pass with rise/peak/set geometry and illumination.', 'additionalProperties': False}, 'description': 'Visible passes (sunlit satellite over a dark-enough sky) in the requested window, chronological.'}, 'norad_id': {'type': 'number', 'description': 'The NORAD catalog number echoed from the request.'}, 'totalCount': {'type': 'number', 'description': 'Number of visible passes found in the window.'}, 'satellite_name': {'type': 'string', 'description': "Satellite name as CelesTrak catalogs it (the element set's OBJECT_NAME)."}, 'resolved_from_name': {'type': 'string', 'description': 'The name query that resolved this object. Present only when the request supplied `name` rather than `norad_id`.'}}, 'additionalProperties': False}
astronomy_get_sky_position
astronomy-mcp-server: get sky position
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.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['latitude', 'longitude'], 'properties': {'body': {'enum': ['sun', 'moon', 'mercury', 'venus', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune', 'pluto'], 'type': 'string', 'description': 'Solar-system body to locate. Omit when targeting a named star via `star`.'}, 'star': {'type': 'string', 'description': 'Named star to locate, from a bundled catalog of 32 stars â\x80\x94 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': {'type': 'string', 'description': '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': {'type': 'number', 'maximum': 90, 'minimum': -90, 'description': 'Observer latitude in decimal degrees, north positive.'}, 'timezone': {'type': 'string', 'description': 'IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only.'}, 'elevation': {'type': 'number', 'default': 0, 'description': 'Observer elevation in meters above sea level. Default 0.'}, 'longitude': {'type': 'number', 'maximum': 180, 'minimum': -180, 'description': 'Observer longitude in decimal degrees, east positive.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'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']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'body': {'type': 'string', 'description': 'The body or star this position is for, echoed from the request.'}, 'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', 'examples': ['invalid_time', 'time_out_of_range', 'invalid_timezone', 'star_not_found', 'body_required'], '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 (â\x89\x881900â\x80\x932100). `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."}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'ecliptic': {'type': 'object', 'required': ['longitude_degrees', 'latitude_degrees'], 'properties': {'latitude_degrees': {'type': 'number', 'description': 'Ecliptic latitude in degrees [-90,90].'}, 'longitude_degrees': {'type': 'number', 'description': 'Ecliptic longitude in degrees [0,360).'}}, 'description': 'Ecliptic-of-date coordinates of the body.', 'additionalProperties': False}, 'time_utc': {'type': 'string', 'description': 'The instant of the observation in ISO 8601 UTC.'}, 'magnitude': {'type': ['number', 'null'], 'description': 'Apparent visual magnitude (lower is brighter). Null for bodies where the engine cannot compute it.'}, 'equatorial': {'type': 'object', 'required': ['ra_hours', 'dec_degrees', 'distance_au'], 'properties': {'ra_hours': {'type': 'number', 'description': 'Right ascension in sidereal hours [0,24), equator-of-date.'}, 'dec_degrees': {'type': 'number', 'description': 'Declination in degrees [-90,90], equator-of-date.'}, 'distance_au': {'type': 'number', 'description': 'Distance from the observer to the body in astronomical units.'}}, 'description': 'Apparent equatorial coordinates, corrected for precession, nutation, parallax, and aberration.', 'additionalProperties': False}, 'horizontal': {'type': 'object', 'required': ['altitude_degrees', 'azimuth_degrees', 'above_horizon'], 'properties': {'above_horizon': {'type': 'boolean', 'description': 'True when the body is above the horizon (altitude > 0).'}, 'azimuth_degrees': {'type': 'number', 'description': 'Compass bearing in degrees: 0=N, 90=E, 180=S, 270=W.'}, 'altitude_degrees': {'type': 'number', 'description': 'Angle above (positive) or below (negative) the horizon, refraction-corrected.'}}, 'description': 'Refraction-corrected horizontal coordinates as seen from the observer.', 'additionalProperties': False}, 'time_local': {'type': 'string', 'description': 'The same instant in the observer-local timezone with offset, present only when a timezone was supplied.'}, 'body_metadata': {'type': 'object', 'required': ['type', 'mean_radius_km', 'naked_eye'], 'properties': {'type': {'enum': ['star', 'planet', 'moon', 'dwarf'], 'type': 'string', 'description': 'Classification of the body.'}, 'naked_eye': {'type': 'boolean', 'description': 'True when the body is typically visible to the naked eye.'}, 'mean_radius_km': {'type': 'number', 'description': 'Mean radius in kilometers, from IAU/NASA fact sheets.'}}, '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.', 'additionalProperties': False}, 'constellation': {'type': 'object', 'required': ['abbreviation', 'name'], 'properties': {'name': {'type': 'string', 'description': 'Full constellation name, e.g. "Orion".'}, 'abbreviation': {'type': 'string', 'description': 'IAU 3-letter constellation abbreviation, e.g. "Ori".'}}, 'description': 'The constellation the body currently falls within.', 'additionalProperties': False}, 'phase_angle_degrees': {'type': ['number', 'null'], 'description': 'Sun-body-observer phase angle in degrees. Null when not applicable (e.g. stars).'}, 'illuminated_fraction': {'type': ['number', 'null'], 'description': 'Fraction of the disc illuminated, 0 to 1. Null when not applicable.'}, 'sun_elongation_degrees': {'type': 'number', '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."}, 'angular_diameter_arcsec': {'type': ['number', 'null'], 'description': 'Apparent angular diameter of the disc in arcseconds. Null for point-source convention bodies.'}}, 'additionalProperties': False}
astronomy_list_visible
astronomy-mcp-server: list visible bodies
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.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['latitude', 'longitude'], 'properties': {'time': {'type': 'string', 'description': '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': {'type': 'number', 'maximum': 90, 'minimum': -90, 'description': 'Observer latitude in decimal degrees, north positive.'}, 'timezone': {'type': 'string', 'description': 'IANA timezone for localized output, e.g. "America/Los_Angeles". When omitted, output is UTC-only.'}, 'elevation': {'type': 'number', 'default': 0, 'description': 'Observer elevation in meters above sea level. Default 0.'}, 'longitude': {'type': 'number', 'maximum': 180, 'minimum': -180, 'description': 'Observer longitude in decimal degrees, east positive.'}, 'min_altitude': {'type': 'number', 'default': 0, 'maximum': 90, 'minimum': -90, 'description': 'Minimum altitude in degrees to include a body. Default 0 (above the horizon); use e.g. 5 to require clearance.'}, 'include_stars': {'type': 'boolean', 'default': False, 'description': 'Include the bundled bright stars alongside planets. Default false.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'anyOf': [{'not': {'required': ['error']}, 'required': ['sky_condition', 'sun_altitude_degrees', 'total_count', 'bodies']}, {'required': ['error']}], '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'error': {'type': 'object', 'required': ['code', 'message'], 'properties': {'code': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'JSON-RPC error code for this failure.'}, 'data': {'type': 'object', 'properties': {'reason': {'type': 'string', 'examples': ['invalid_time', 'time_out_of_range', 'invalid_timezone'], '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 (â\x89\x881900â\x80\x932100). `invalid_timezone`: The `timezone` value is not an IANA zone this runtime knows. Other values are possible when a failure originates below the handler."}, 'recovery': {'type': 'object', 'required': ['hint'], 'properties': {'hint': {'type': 'string'}}, 'description': 'Actionable next step for the caller.', 'additionalProperties': {}}, 'retryable': {'type': 'boolean', 'description': 'Whether retrying may succeed.'}}, 'additionalProperties': {}}, 'message': {'type': 'string', 'description': 'Human-readable description of what went wrong.'}}, 'description': 'Present when the call failed. Absent on success.', 'additionalProperties': {}}, 'bodies': {'type': 'array', 'items': {'type': 'object', 'required': ['body', 'time_utc', 'equatorial', 'horizontal', 'ecliptic', 'magnitude', 'angular_diameter_arcsec', 'phase_angle_degrees', 'illuminated_fraction', 'sun_elongation_degrees', 'constellation', 'rank', 'visibility_note'], 'properties': {'body': {'type': 'string', 'description': 'The body or star this position is for, echoed from the request.'}, 'rank': {'type': 'number', 'description': '1-based rank, brightest-and-highest first.'}, 'ecliptic': {'type': 'object', 'required': ['longitude_degrees', 'latitude_degrees'], 'properties': {'latitude_degrees': {'type': 'number', 'description': 'Ecliptic latitude in degrees [-90,90].'}, 'longitude_degrees': {'type': 'number', 'description': 'Ecliptic longitude in degrees [0,360).'}}, 'description': 'Ecliptic-of-date coordinates of the body.', 'additionalProperties': False}, 'time_utc': {'type': 'string', 'description': 'The instant of the observation in ISO 8601 UTC.'}, 'magnitude': {'type': ['number', 'null'], 'description': 'Apparent visual magnitude (lower is brighter). Null for bodies where the engine cannot compute it.'}, 'equatorial': {'type': 'object', 'required': ['ra_hours', 'dec_degrees', 'distance_au'], 'properties': {'ra_hours': {'type': 'number', 'description': 'Right ascension in sidereal hours [0,24), equator-of-date.'}, 'dec_degrees': {'type': 'number', 'description': 'Declination in degrees [-90,90], equator-of-date.'}, 'distance_au': {'type': 'number', 'description': 'Distance from the observer to the body in astronomical units.'}}, 'description': 'Apparent equatorial coordinates, corrected for precession, nutation, parallax, and aberration.', 'additionalProperties': False}, 'horizontal': {'type': 'object', 'required': ['altitude_degrees', 'azimuth_degrees', 'above_horizon'], 'properties': {'above_horizon': {'type': 'boolean', 'description': 'True when the body is above the horizon (altitude > 0).'}, 'azimuth_degrees': {'type': 'number', 'description': 'Compass bearing in degrees: 0=N, 90=E, 180=S, 270=W.'}, 'altitude_degrees': {'type': 'number', 'description': 'Angle above (positive) or below (negative) the horizon, refraction-corrected.'}}, 'description': 'Refraction-corrected horizontal coordinates as seen from the observer.', 'additionalProperties': False}, 'time_local': {'type': 'string', 'description': 'The same instant in the observer-local timezone with offset, present only when a timezone was supplied.'}, 'constellation': {'type': 'object', 'required': ['abbreviation', 'name'], 'properties': {'name': {'type': 'string', 'description': 'Full constellation name, e.g. "Orion".'}, 'abbreviation': {'type': 'string', 'description': 'IAU 3-letter constellation abbreviation, e.g. "Ori".'}}, 'description': 'The constellation the body currently falls within.', 'additionalProperties': False}, 'visibility_note': {'type': 'string', 'description': 'Server-computed one-line headline from real values, e.g. "Venus, mag -4.1, 12° above the WSW horizon â\x80\x94 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.'}, 'phase_angle_degrees': {'type': ['number', 'null'], 'description': 'Sun-body-observer phase angle in degrees. Null when not applicable (e.g. stars).'}, 'illuminated_fraction': {'type': ['number', 'null'], 'description': 'Fraction of the disc illuminated, 0 to 1. Null when not applicable.'}, 'sun_elongation_degrees': {'type': 'number', '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."}, 'angular_diameter_arcsec': {'type': ['number', 'null'], 'description': 'Apparent angular diameter of the disc in arcseconds. Null for point-source convention bodies.'}}, 'description': 'A sky position above the horizon, with its rank and a plain-language visibility note.', 'additionalProperties': False}, 'description': 'Every body (and optional star) above the minimum-altitude filter, ranked brightest-and-highest first.'}, 'total_count': {'type': 'number', 'description': 'Number of bodies returned above the minimum-altitude filter.'}, 'sky_condition': {'enum': ['daylight', 'civil_twilight', 'nautical_twilight', 'astronomical_twilight', 'dark'], 'type': 'string', 'description': "Sky condition derived from the Sun's altitude â\x80\x94 the gate for whether faint objects are observable."}, 'sun_altitude_degrees': {'type': 'number', 'description': "The Sun's altitude in degrees that produced the sky condition."}}, 'additionalProperties': False}
已更改
astronomy_get_satellite_passes
2026年9月25日 02:51
已更改
astronomy_get_ephemeris
2026年9月25日 02:51
已更改
astronomy_list_visible
2026年9月25日 02:51
已更改
astronomy_find_events
2026年9月25日 02:51
已更改
astronomy_get_moon_phase
2026年9月25日 02:51
已更改
astronomy_get_rise_set
2026年9月25日 02:51
已更改
astronomy_get_sky_position
2026年9月25日 02:51
已更改
astronomy_get_ephemeris
2026年9月21日 02:50
已更改
astronomy_list_visible
2026年9月21日 02:50
已更改
astronomy_find_events
2026年9月21日 02:50
已更改
astronomy_get_rise_set
2026年9月21日 02:50
已更改
astronomy_get_sky_position
2026年9月21日 02:50
已添加
astronomy_get_satellite_passes
2026年9月17日 12:41
已添加
astronomy_get_ephemeris
2026年9月17日 12:41
已添加
astronomy_list_visible
2026年9月17日 12:41
已添加
astronomy_find_events
2026年9月17日 12:41
已添加
astronomy_get_moon_phase
2026年9月17日 12:41
已添加
astronomy_get_rise_set
2026年9月17日 12:41
已添加
astronomy_get_sky_position
2026年9月17日 12:41