Skip to main content
Glama

Sunrise, sunset and twilight

astro_sun
Read-onlyIdempotent

The complete solar day for one location: sunrise, sunset, solar noon, day length, civil, nautical and astronomical twilight boundaries, and explicit polar day/night status at high latitudes. Location required. For a series, send start and end (step is whole days, e.g. "1d" or "7d"). For "is it dark enough to observe" prefer astro_dark_window; for a broad snapshot prefer astro_sky_today.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tzNoIANA timezone like "Europe/Lisbon" to render event times in local time. Optional; a resolved place supplies its own timezone.
endNoLast day of a range. ISO 8601 UTC date or datetime, e.g. "2026-08-06" or "2026-08-06T21:00:00Z". Or jd: followed by a Julian Day on the UT scale, e.g. "jd:2461000.5". On astro_positions, date may list up to 24 datetimes separated by commas, answered in the order sent. Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there.
latNoLatitude in decimal degrees, north positive. Send lat and lon together.
lonNoLongitude in decimal degrees, east positive (Lisbon is about -9.14). Send lat and lon together.
dateNoSingle day to report, ISO 8601 UTC date or datetime, e.g. "2026-08-06" or "2026-08-06T21:00:00Z". Or jd: followed by a Julian Day on the UT scale, e.g. "jd:2461000.5". On astro_positions, date may list up to 24 datetimes separated by commas, answered in the order sent. Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there.
stepNoRange stride in whole days, e.g. "1d", "7d", "30d". Default "1d".
placeNoPlace name instead of lat/lon, as "City" or "City,CC" with an ISO country code, e.g. "Lisbon,PT". Resolved server-side; the response then carries a required GeoNames CC BY 4.0 credit in its attribution field, which must be preserved when shown.
startNoFirst day of a range (use with end instead of date). ISO 8601 UTC date or datetime, e.g. "2026-08-06" or "2026-08-06T21:00:00Z". Or jd: followed by a Julian Day on the UT scale, e.g. "jd:2461000.5". On astro_positions, date may list up to 24 datetimes separated by commas, answered in the order sent. Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there.
cursorNoOpaque pagination cursor from a previous result's next_cursor. Send it with the same start/end arguments as the first page.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataYesThe complete solar day for one location, or one row per day in range mode.
rightsNoEither unrestricted, or attribution_required when third-party place data was used. When attribution_required, the attribution line must be shown.
warningsNoMachine-readable notices about this answer. Present only when non-empty. Never changes whether the call succeeded.
attributionNoThe credit line to display verbatim when rights is attribution_required.
next_cursorNoPresent only when more rows exist. Send it back with the SAME start/end arguments as the first call to get the next page.
not_computedNoData this API deliberately does not serve, and why. Present only when the question touched such a field. An absence named here is information: treat it as "withheld", never as "none exists".

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / properties / date / description
      Previous value: -"Single day to report, ISO 8601 UTC date or datetime, e.g. \"2026-08-06\" or \"2026-08-06T21:00:00Z\". Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there."New value: +"Single day to report, ISO 8601 UTC date or datetime, e.g. \"2026-08-06\" or \"2026-08-06T21:00:00Z\". Or jd: followed by a Julian Day on the UT scale, e.g. \"jd:2461000.5\". On astro_positions, date may list up to 24 datetimes separated by commas, answered in the order sent. Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there."
    • changedInput schema / properties / end / description
      Previous value: -"Last day of a range. ISO 8601 UTC date or datetime, e.g. \"2026-08-06\" or \"2026-08-06T21:00:00Z\". Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there."New value: +"Last day of a range. ISO 8601 UTC date or datetime, e.g. \"2026-08-06\" or \"2026-08-06T21:00:00Z\". Or jd: followed by a Julian Day on the UT scale, e.g. \"jd:2461000.5\". On astro_positions, date may list up to 24 datetimes separated by commas, answered in the order sent. Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there."
    • changedInput schema / properties / start / description
      Previous value: -"First day of a range (use with end instead of date). ISO 8601 UTC date or datetime, e.g. \"2026-08-06\" or \"2026-08-06T21:00:00Z\". Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there."New value: +"First day of a range (use with end instead of date). ISO 8601 UTC date or datetime, e.g. \"2026-08-06\" or \"2026-08-06T21:00:00Z\". Or jd: followed by a Julian Day on the UT scale, e.g. \"jd:2461000.5\". On astro_positions, date may list up to 24 datetimes separated by commas, answered in the order sent. Omit for the current moment. Years 1700 to 2200 only; outside that range the API refuses with DATE_OUT_OF_RANGE because the ephemeris is not reliable there."
  2. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "additionalProperties": true,
      +  "description": "The MCP projection of a CycleCalcs v2 response: the answer, plus the provenance a caller needs to use it honestly.",
      +  "properties": {
      +    "attribution": {
      +      "description": "The credit line to display verbatim when rights is attribution_required.",
      +      "type": "string"
      +    },
      +    "data": {
      +      "additionalProperties": true,
      +      "description": "The complete solar day for one location, or one row per day in range mode.",
      +      "properties": {
      +        "blue_hour": {
      +          "description": "The blue-light window just outside golden hour.",
      +          "type": "object"
      +        },
      +        "constellation": {
      +          "description": "The IAU constellation the Sun currently occupies.",
      +          "type": "object"
      +        },
      +        "custom": {
      +          "description": "Boundaries for any custom depression angles requested.",
      +          "type": "array"
      +        },
      +        "dark_minutes": {
      +          "description": "Minutes of true astronomical darkness.",
      +          "type": "integer"
      +        },
      +        "day_length": {
      +          "description": "Day length, human-readable.",
      +          "type": "string"
      +        },
      +        "day_length_change_from_yesterday_seconds": {
      +          "description": "Seconds gained or lost since the previous day. Negative means shortening.",
      +          "type": "integer"
      +        },
      +        "day_length_minutes": {
      +          "description": "Day length in minutes.",
      +          "type": "number"
      +        },
      +        "day_length_seconds": {
      +          "description": "Day length in whole seconds.",
      +          "type": "integer"
      +        },
      +        "days": {
      +          "description": "RANGE MODE ONLY: one entry per day, each with the fields above.",
      +          "type": "array"
      +        },
      +        "golden_hour": {
      +          "description": "The warm-light window around sunrise and sunset.",
      +          "type": "object"
      +        },
      +        "night_begins": {
      +          "description": "When astronomical night starts. Null where it never gets that dark.",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "night_ends": {
      +          "description": "When astronomical night ends. Null where it never gets that dark.",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "position_now": {
      +          "description": "Where the Sun is at this moment.",
      +          "type": "object"
      +        },
      +        "rise_set": {
      +          "description": "Sunrise and sunset, with a status for polar day and polar night.",
      +          "type": "object"
      +        },
      +        "solar_midnight": {
      +          "description": "Instant the Sun is lowest, opposite solar noon.",
      +          "type": "string"
      +        },
      +        "solar_midnight_altitude_deg": {
      +          "description": "Sun altitude at solar midnight, in degrees.",
      +          "type": "number"
      +        },
      +        "solar_midnight_altitude_refracted_deg": {
      +          "description": "Including refraction.",
      +          "type": "number"
      +        },
      +        "solar_midnight_altitude_unrefracted_deg": {
      +          "description": "Geometric, refraction excluded.",
      +          "type": "number"
      +        },
      +        "solar_noon": {
      +          "description": "Instant the Sun crosses the meridian.",
      +          "type": "string"
      +        },
      +        "solar_noon_altitude_deg": {
      +          "description": "Sun altitude at solar noon, in degrees.",
      +          "type": "number"
      +        },
      +        "solar_noon_altitude_refracted_deg": {
      +          "description": "As seen, including atmospheric refraction.",
      +          "type": "number"
      +        },
      +        "solar_noon_altitude_unrefracted_deg": {
      +          "description": "Geometric altitude, refraction excluded.",
      +          "type": "number"
      +        },
      +        "solar_noon_azimuth_deg": {
      +          "description": "Compass bearing of the Sun at solar noon.",
      +          "type": "number"
      +        },
      +        "summary": {
      +          "description": "A one-line reading of the solar day.",
      +          "type": "string"
      +        },
      +        "tropical_sign": {
      +          "description": "Tropical ecliptic longitude, reported as position only.",
      +          "type": "object"
      +        },
      +        "twilight": {
      +          "description": "Civil, nautical and astronomical twilight boundaries.",
      +          "type": "object"
      +        },
      +        "window": {
      +          "description": "The instant or range actually evaluated, after parsing.",
      +          "type": "object"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "next_cursor": {
      +      "description": "Present only when more rows exist. Send it back with the SAME start/end arguments as the first call to get the next page.",
      +      "type": "string"
      +    },
      +    "not_computed": {
      +      "description": "Data this API deliberately does not serve, and why. Present only when the question touched such a field. An absence named here is information: treat it as \"withheld\", never as \"none exists\".",
      +      "type": "array"
      +    },
      +    "rights": {
      +      "description": "Either unrestricted, or attribution_required when third-party place data was used. When attribution_required, the attribution line must be shown.",
      +      "type": "string"
      +    },
      +    "warnings": {
      +      "description": "Machine-readable notices about this answer. Present only when non-empty. Never changes whether the call succeeded.",
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "data"
      +  ],
      +  "type": "object"
      +}
  3. First observed

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds real behavioral context beyond that: explicit polar day/night handling at high latitudes and tz-driven local rendering. It stops short of describing pagination/cursor behavior or error modes, which the schema covers instead.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: capability first, then the location/range mechanics, then sibling routing. Every sentence earns its place with zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not required, yet the description still names the key outputs and the polar edge case. Combined with 100% schema coverage and full annotations, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents lat/lon/tz/date/start/end/step/cursor with format details and the 1700–2200 range. The description only restates 'Location required' and the step format already given in the schema, adding no new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb/resource (complete solar day for one location) and enumerates exactly what is returned: sunrise, sunset, solar noon, day length, three twilight boundaries, and polar day/night status. This distinguishes it cleanly from siblings like astro_rise_set and astro_dark_window.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the location requirement, gives the range pattern (send start and end, step in whole days with examples), and routes to alternatives with conditions: astro_dark_window for 'is it dark enough to observe' and astro_sky_today for a broad snapshot.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources